/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single TCP/UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif

#include "syshead.h"

#include "status.h"
#include "perf.h"
#include "misc.h"
#include "fdmisc.h"

#include "memdbg.h"

/*
 * printf-style interface for outputting status info
 */

static const char *
print_status_mode(unsigned int flags)
{
    switch (flags)
    {
        case STATUS_OUTPUT_WRITE:
            return "WRITE";

        case STATUS_OUTPUT_READ:
            return "READ";

        case STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE:
            return "READ/WRITE";

        default:
            return "UNDEF";
    }
}

struct status_output *
status_open(const char *filename,
            const int refresh_freq,
            const int msglevel,
            const struct virtual_output *vout,
            const unsigned int flags)
{
    struct status_output *so = NULL;
    if (filename || msglevel >= 0 || vout)
    {
        ALLOC_OBJ_CLEAR(so, struct status_output);
        so->flags = flags;
        so->msglevel = msglevel;
        so->vout = vout;
        so->fd = -1;
        buf_reset(&so->read_buf);
        event_timeout_clear(&so->et);
        if (filename)
        {
            switch (so->flags)
            {
                case STATUS_OUTPUT_WRITE:
                    so->fd = platform_open(filename,
                                           O_CREAT | O_TRUNC | O_WRONLY,
                                           S_IRUSR | S_IWUSR);
                    break;

                case STATUS_OUTPUT_READ:
                    so->fd = platform_open(filename,
                                           O_RDONLY,
                                           S_IRUSR | S_IWUSR);
                    break;

                case STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE:
                    so->fd = platform_open(filename,
                                           O_CREAT | O_RDWR,
                                           S_IRUSR | S_IWUSR);
                    break;

                default:
                    ASSERT(0);
            }
            if (so->fd >= 0)
            {
                so->filename = string_alloc(filename, NULL);
                set_cloexec(so->fd);

                /* allocate read buffer */
                if (so->flags & STATUS_OUTPUT_READ)
                {
                    so->read_buf = alloc_buf(512);
                }
            }
            else
            {
                msg(M_WARN, "Note: cannot open %s for %s", filename, print_status_mode(so->flags));
                so->errors = true;
            }
        }
        else
        {
            so->flags = STATUS_OUTPUT_WRITE;
        }

        if ((so->flags & STATUS_OUTPUT_WRITE) && refresh_freq > 0)
        {
            event_timeout_init(&so->et, refresh_freq, 0);
        }
    }
    return so;
}

bool
status_trigger(struct status_output *so)
{
    if (so)
    {
        struct timeval null;
        CLEAR(null);
        return event_timeout_trigger(&so->et, &null, ETT_DEFAULT);
    }
    else
    {
        return false;
    }
}

bool
status_trigger_tv(struct status_output *so, struct timeval *tv)
{
    if (so)
    {
        return event_timeout_trigger(&so->et, tv, ETT_DEFAULT);
    }
    else
    {
        return false;
    }
}

void
status_reset(struct status_output *so)
{
    if (so && so->fd >= 0)
    {
        lseek(so->fd, (off_t)0, SEEK_SET);
    }
}

void
status_flush(struct status_output *so)
{
    if (so && so->fd >= 0 && (so->flags & STATUS_OUTPUT_WRITE))
    {
#if defined(HAVE_FTRUNCATE)
        {
            const off_t off = lseek(so->fd, (off_t)0, SEEK_CUR);
            if (ftruncate(so->fd, off) != 0)
            {
                msg(M_WARN | M_ERRNO, "Failed to truncate status file");
            }
        }
#elif defined(HAVE_CHSIZE)
        {
            const long off = (long) lseek(so->fd, (off_t)0, SEEK_CUR);
            chsize(so->fd, off);
        }
#else  /* if defined(HAVE_FTRUNCATE) */
#warning both ftruncate and chsize functions appear to be missing from this OS
#endif

        /* clear read buffer */
        if (buf_defined(&so->read_buf))
        {
            ASSERT(buf_init(&so->read_buf, 0));
        }
    }
}

/* return false if error occurred */
bool
status_close(struct status_output *so)
{
    bool ret = true;
    if (so)
    {
        if (so->errors)
        {
            ret = false;
        }
        if (so->fd >= 0)
        {
            if (close(so->fd) < 0)
            {
                ret = false;
            }
        }
        if (so->filename)
        {
            free(so->filename);
        }
        if (buf_defined(&so->read_buf))
        {
            free_buf(&so->read_buf);
        }
        free(so);
    }
    else
    {
        ret = false;
    }
    return ret;
}

#define STATUS_PRINTF_MAXLEN 512

void
status_printf(struct status_output *so, const char *format, ...)
{
    if (so && (so->flags & STATUS_OUTPUT_WRITE))
    {
        char buf[STATUS_PRINTF_MAXLEN+2]; /* leave extra bytes for CR, LF */
        va_list arglist;
        int stat;

        va_start(arglist, format);
        stat = vsnprintf(buf, STATUS_PRINTF_MAXLEN, format, arglist);
        va_end(arglist);
        buf[STATUS_PRINTF_MAXLEN - 1] = 0;

        if (stat < 0 || stat >= STATUS_PRINTF_MAXLEN)
        {
            so->errors = true;
        }

        if (so->msglevel >= 0 && !so->errors)
        {
            msg(so->msglevel, "%s", buf);
        }

        if (so->fd >= 0 && !so->errors)
        {
            int len;
            strcat(buf, "\n");
            len = strlen(buf);
            if (len > 0)
            {
                if (write(so->fd, buf, len) != len)
                {
                    so->errors = true;
                }
            }
        }

        if (so->vout && !so->errors)
        {
            chomp(buf);
            (*so->vout->func)(so->vout->arg, so->vout->flags_default, buf);
        }
    }
}

bool
status_read(struct status_output *so, struct buffer *buf)
{
    bool ret = false;

    if (so && so->fd >= 0 && (so->flags & STATUS_OUTPUT_READ))
    {
        ASSERT(buf_defined(&so->read_buf));
        ASSERT(buf_defined(buf));
        while (true)
        {
            const int c = buf_read_u8(&so->read_buf);

            /* read more of file into buffer */
            if (c == -1)
            {
                int len;

                ASSERT(buf_init(&so->read_buf, 0));
                len = read(so->fd, BPTR(&so->read_buf), BCAP(&so->read_buf));
                if (len <= 0)
                {
                    break;
                }

                ASSERT(buf_inc_len(&so->read_buf, len));
                continue;
            }

            ret = true;

            if (c == '\r')
            {
                continue;
            }

            if (c == '\n')
            {
                break;
            }

            buf_write_u8(buf, c);
        }

        buf_null_terminate(buf);
    }

    return ret;
}
