/**
 * @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 "config.hpp"
#include "log_manager.hpp"

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

// 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;
}
