// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/directory.h>
#include <lib/zx/channel.h>
#include <lib/zx/socket.h>
#include <lib/syslog/logger.h>

// TODO: Remove this hack once FIDL-182  is fixed.
typedef zx_handle_t fuchsia_logger_LogListener;
#include <fuchsia/logger/c/fidl.h>

#include "fx_logger.h"

namespace {

zx::socket connect_to_logger() {
    zx::socket invalid;
    zx::channel logger, logger_request;
    if (zx::channel::create(0, &logger, &logger_request) != ZX_OK) {
        return invalid;
    }
    if (fdio_service_connect("/svc/fuchsia.logger.LogSink", logger_request.release()) != ZX_OK) {
        return invalid;
    }
    zx::socket local, remote;
    if (zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote) != ZX_OK) {
        return invalid;
    }
    fuchsia_logger_LogSinkConnectRequest req;
    memset(&req, 0, sizeof(req));
    req.hdr.ordinal = fuchsia_logger_LogSinkConnectOrdinal;
    req.socket = FIDL_HANDLE_PRESENT;
    zx_handle_t handles[1] = {remote.release()};
    if (logger.write(0, &req, sizeof(req), handles, 1) != ZX_OK) {
        close(handles[0]);
        return invalid;
    }
    return local;
}

} // namespace
zx_status_t fx_logger_logf(fx_logger_t* logger, fx_log_severity_t severity,
                           const char* tag, const char* format, ...) {
    if (logger == nullptr) {
        return ZX_ERR_BAD_STATE;
    }
    va_list args;
    va_start(args, format);
    zx_status_t s = logger->VLogWrite(severity, tag, format, args);
    va_end(args);
    return s;
}

zx_status_t fx_logger_log(fx_logger_t* logger, fx_log_severity_t severity,
                          const char* tag, const char* msg) {
    if (logger == nullptr) {
        return ZX_ERR_BAD_STATE;
    }
    return logger->LogWrite(severity, tag, msg);
}

zx_status_t fx_vlogf(fx_logger_t* logger, fx_log_severity_t severity,
                     const char* tag, const char* format, va_list args) {
    if (logger == nullptr) {
        return ZX_ERR_BAD_STATE;
    }
    return logger->VLogWrite(severity, tag, format, args);
}

fx_log_severity_t fx_logger_get_min_severity(fx_logger_t* logger) {
    if (logger == nullptr) {
        return FX_LOG_FATAL;
    }
    return logger->GetSeverity();
}

void fx_logger_set_min_severity(fx_logger_t* logger,
                                fx_log_severity_t severity) {
    return logger->SetSeverity(severity);
}

void fx_logger_activate_fallback(fx_logger_t* logger,
                                 int fallback_fd) {
    logger->ActivateFallback(fallback_fd);
}

zx_status_t fx_logger_create(const fx_logger_config_t* config,
                             fx_logger_t** out_logger) {
    if (config->num_tags > FX_LOG_MAX_TAGS) {
        return ZX_ERR_INVALID_ARGS;
    }
    fx_logger_config_t c = *config;
    if (config->console_fd == -1 &&
        config->log_service_channel == ZX_HANDLE_INVALID) {
        zx::socket sock = connect_to_logger();
        if (sock.is_valid()) {
            c.log_service_channel = sock.release();
        } else {
            int newfd = dup(STDERR_FILENO);
            if (newfd < 0) {
                return ZX_ERR_INTERNAL;
            }
            c.console_fd = newfd;
        }
    }
    *out_logger = new fx_logger(&c);
    return ZX_OK;
}

void fx_logger_destroy(fx_logger_t* logger) {
    delete logger;
}
