/**
 * @brief Log manager.
 *
 * This file is part of HostLogger project.
 *
 * Copyright (c) 2018 YADRO
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "log_manager.hpp"

#include "config.hpp"

#include <dirent.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#include <cstring>
#include <set>
#include <vector>

// Path to the Unix Domain socket file used to read host's logs
#define HOSTLOG_SOCKET_PATH "\0obmc-console"
// Number of connection attempts
#define HOSTLOG_SOCKET_ATTEMPTS 60
// Pause between connection attempts in seconds
#define HOSTLOG_SOCKET_PAUSE 1
// Max buffer size to read from socket
#define MAX_SOCKET_BUFFER_SIZE 512

LogManager::LogManager() : fd_(-1)
{
}

LogManager::~LogManager()
{
    closeHostLog();
}

int LogManager::openHostLog()
{
    int rc;

    do
    {
        // Create socket
        fd_ = socket(AF_UNIX, SOCK_STREAM, 0);
        if (fd_ == -1)
        {
            rc = errno;
            fprintf(stderr, "Unable to create socket: error [%i] %s\n", rc,
                    strerror(rc));
            break;
        }

        // Set non-blocking mode for socket
        int opt = 1;
        rc = ioctl(fd_, FIONBIO, &opt);
        if (rc != 0)
        {
            rc = errno;
            fprintf(stderr,
                    "Unable to set non-blocking mode for log socket: error "
                    "[%i] %s\n",
                    rc, strerror(rc));
            break;
        }

        sockaddr_un sa = {0};
        sa.sun_family = AF_UNIX;
        constexpr int min_path =
            sizeof(HOSTLOG_SOCKET_PATH) < sizeof(sa.sun_path)
                ? sizeof(HOSTLOG_SOCKET_PATH)
                : sizeof(sa.sun_path);
        memcpy(&sa.sun_path, HOSTLOG_SOCKET_PATH, min_path);

        // Connect to host's log stream via socket.
        // The owner of the socket (server) is obmc-console service and
        // we have a dependency on it written in the systemd unit file, but
        // we can't guarantee that the socket is initialized at the moment.
        rc = -1;
        for (int attempt = 0; rc != 0 && attempt < HOSTLOG_SOCKET_ATTEMPTS;
             ++attempt)
        {
            rc = connect(fd_, reinterpret_cast<const sockaddr*>(&sa),
                         sizeof(sa));
            sleep(HOSTLOG_SOCKET_PAUSE);
        }
        if (rc < 0)
        {
            rc = errno;
            fprintf(stderr,
                    "Unable to connect to host log socket: error [%i] %s\n", rc,
                    strerror(rc));
        }
    } while (false);

    if (rc != 0)
        closeHostLog();

    return rc;
}

void LogManager::closeHostLog()
{
    if (fd_ != -1)
    {
        ::close(fd_);
        fd_ = -1;
    }
}

int LogManager::getHostLogFd() const
{
    return fd_;
}

int LogManager::handleHostLog()
{
    int rc = 0;
    std::vector<char> buff(MAX_SOCKET_BUFFER_SIZE);
    size_t readLen = MAX_SOCKET_BUFFER_SIZE;

    // Read all existing data from log stream
    while (rc == 0 && readLen != 0)
    {
        rc = readHostLog(&buff[0], buff.size(), readLen);
        if (rc == 0 && readLen != 0)
            storage_.parse(&buff[0], readLen);
    }

    return rc;
}

int LogManager::flush()
{
    int rc;

    if (storage_.empty())
        return 0; // Nothing to save

    const std::string logFile = prepareLogPath();
    if (logFile.empty())
        return EIO;

    rc = storage_.write(logFile.c_str());
    if (rc != 0)
        return rc;

    storage_.clear();

    // Non critical tasks, don't check returned status
    rotateLogFiles();

    return 0;
}

int LogManager::readHostLog(char* buffer, size_t bufferLen,
                            size_t& readLen) const
{
    int rc = 0;

    const ssize_t rsz = ::read(fd_, buffer, bufferLen);
    if (rsz >= 0)
        readLen = static_cast<size_t>(rsz);
    else
    {
        readLen = 0;
        if (errno != EAGAIN && errno != EWOULDBLOCK)
        {
            rc = errno;
            fprintf(stderr, "Unable to read host log: error [%i] %s\n", rc,
                    strerror(rc));
        }
    }

    return rc;
}

std::string LogManager::prepareLogPath() const
{
    // Create path for logs
    if (::access(loggerConfig.path, F_OK) != 0)
    {
        const std::string logPath(loggerConfig.path);
        const size_t len = logPath.length();
        size_t pos = 0;
        while (pos < len - 1)
        {
            pos = logPath.find('/', pos + 1);
            const std::string createPath = logPath.substr(0, pos);
            if (::mkdir(createPath.c_str(),
                        S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0 &&
                errno != EEXIST)
            {
                const int rc = errno;
                fprintf(stderr, "Unable to create dir %s: error [%i] %s\n",
                        createPath.c_str(), rc, strerror(rc));
                return std::string();
            }
        }
    }

    // Construct log file name
    time_t ts;
    time(&ts);
    tm lt = {0};
    localtime_r(&ts, &lt);
    char fileName[64];
    snprintf(fileName, sizeof(fileName), "/host_%i%02i%02i_%02i%02i%02i.log.gz",
             lt.tm_year + 1900, lt.tm_mon + 1, lt.tm_mday, lt.tm_hour,
             lt.tm_min, lt.tm_sec);

    return std::string(loggerConfig.path) + fileName;
}

int LogManager::rotateLogFiles() const
{
    if (loggerConfig.rotationLimit == 0)
        return 0; // Not applicable

    int rc = 0;

    // Get file list to std::set
    std::set<std::string> logFiles;
    DIR* dh = opendir(loggerConfig.path);
    if (!dh)
    {
        rc = errno;
        fprintf(stderr, "Unable to open directory %s: error [%i] %s\n",
                loggerConfig.path, rc, strerror(rc));
        return rc;
    }
    dirent* dir;
    while ((dir = readdir(dh)))
    {
        if (dir->d_type != DT_DIR)
            logFiles.insert(dir->d_name);
    }
    closedir(dh);

    // Log file has a name with a timestamp generated by prepareLogPath().
    // The sorted array of names (std::set) will contain the oldest file on the
    // top.
    // Remove oldest files.
    int filesToRemove =
        static_cast<int>(logFiles.size()) - loggerConfig.rotationLimit;
    while (rc == 0 && --filesToRemove >= 0)
    {
        std::string fileToRemove = loggerConfig.path;
        fileToRemove += '/';
        fileToRemove += *logFiles.begin();
        if (::unlink(fileToRemove.c_str()) == -1)
        {
            rc = errno;
            fprintf(stderr, "Unable to delete file %s: error [%i] %s\n",
                    fileToRemove.c_str(), rc, strerror(rc));
        }
        logFiles.erase(fileToRemove);
    }

    return rc;
}
