// 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 <runtests-utils/log-exporter.h>

#include <errno.h>
#include <stdint.h>

#include <fuchsia/logger/c/fidl.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/directory.h>
#include <lib/fidl/cpp/message_buffer.h>
#include <lib/zx/channel.h>
#include <zircon/status.h>

#include <utility>

namespace runtests {
namespace {

fbl::String ToFblString(fidl_string_t string) {
    return fbl::String(string.data, string.size);
}

} // namespace

LogExporter::LogExporter(zx::channel channel, FILE* output_file)
    : loop_(&kAsyncLoopConfigNoAttachToThread),
      channel_(std::move(channel)),
      wait_(this, channel_.get(), ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED),
      output_file_(output_file) {
    wait_.Begin(loop_.dispatcher());
}

LogExporter::~LogExporter() {
    // Quit so that current work is completed and loop can stop.
    loop_.Quit();

    // wait for current work to be completed.
    loop_.JoinThreads();

    // Run one more time until there are no more messages.
    loop_.ResetQuit();
    RunUntilIdle();

    // Shutdown
    loop_.Shutdown();
    if (output_file_ != nullptr) {
        fclose(output_file_);
    }
}

zx_status_t LogExporter::StartThread() {
    return loop_.StartThread();
}

zx_status_t LogExporter::RunUntilIdle() {
    return loop_.RunUntilIdle();
}

void LogExporter::OnHandleReady(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                                const zx_packet_signal_t* signal) {
    if (status != ZX_OK) {
        NotifyError(status);
        return;
    }

    if (signal->observed & ZX_CHANNEL_READABLE) {
        fidl::MessageBuffer buffer;
        for (uint64_t i = 0; i < signal->count; i++) {
            status = ReadAndDispatchMessage(&buffer);
            if (status == ZX_ERR_SHOULD_WAIT) {
                break;
            } else if (status != ZX_OK) {
                NotifyError(status);
                return;
            }
        }
        status = wait_.Begin(dispatcher);
        if (status != ZX_OK) {
            NotifyError(status);
        }
        return;
    }

    ZX_DEBUG_ASSERT(signal->observed & ZX_CHANNEL_PEER_CLOSED);

    // We don't notify an error until we've drained all the messages.
    NotifyError(ZX_ERR_PEER_CLOSED);
}

zx_status_t LogExporter::ReadAndDispatchMessage(fidl::MessageBuffer* buffer) {
    fidl::Message message = buffer->CreateEmptyMessage();
    zx_status_t status = message.Read(channel_.get(), 0);
    if (status != ZX_OK) {
        return status;
    }
    if (!message.has_header()) {
        return ZX_ERR_INVALID_ARGS;
    }

    // This is an if statement because, depending on the state of the ordinal
    // migration, GenOrdinal and Ordinal may be the same value.  See FIDL-524.
    uint32_t ordinal = message.ordinal();
    if (ordinal == fuchsia_logger_LogListenerLogGenOrdinal ||
        ordinal == fuchsia_logger_LogListenerLogOrdinal) {
        return Log(std::move(message));
    } else if (ordinal == fuchsia_logger_LogListenerLogManyGenOrdinal ||
               ordinal == fuchsia_logger_LogListenerLogManyOrdinal) {
        return LogMany(std::move(message));
    } else {
        return ZX_ERR_NOT_SUPPORTED;
    }
}

// Returns only seconds part
uint64_t GetSeconds(uint64_t nanoseconds) {
    return nanoseconds / 1000000000UL;
}

// Returns only nano seconds part
uint64_t GetNanoSeconds(uint64_t nanoseconds) {
    return (nanoseconds / 1000UL) % 1000000UL;
}

#define RETURN_IF_ERROR(expr) \
    do {                      \
        int n = (expr);       \
        if (n < 0) {          \
            return n;         \
        }                     \
    } while (false)

int LogExporter::WriteSeverity(int32_t severity) {
    switch (severity) {
    case fuchsia_logger_LogLevelFilter_INFO:
        return fputs(" INFO", output_file_);
    case fuchsia_logger_LogLevelFilter_WARN:
        return fputs(" WARNING", output_file_);
    case fuchsia_logger_LogLevelFilter_ERROR:
        return fputs(" ERROR", output_file_);
    case fuchsia_logger_LogLevelFilter_FATAL:
        return fputs(" FATAL", output_file_);
    default:
        // all other cases severity would be a negative nuber so print it as
        // VLOG(n) where severity=-n
        return fprintf(output_file_, " VLOG(%d)", -severity);
    }
}

int LogExporter::LogMessage(fuchsia_logger_LogMessage* log_message) {
    RETURN_IF_ERROR(fprintf(output_file_, "[%05ld.%06ld][%lu][%lu]", GetSeconds(log_message->time),
                            GetNanoSeconds(log_message->time), log_message->pid, log_message->tid));
    RETURN_IF_ERROR(fputs("[", output_file_));
    fidl_string_t* tags = static_cast<fidl_string_t*>(log_message->tags.data);
    for (size_t i = 0; i < log_message->tags.count; ++i) {
        RETURN_IF_ERROR(fprintf(output_file_, "%s", ToFblString(tags[i]).c_str()));
        if (i < log_message->tags.count - 1) {
            RETURN_IF_ERROR(fputs(", ", output_file_));
        }
    }
    RETURN_IF_ERROR(fputs("]", output_file_));

    RETURN_IF_ERROR(WriteSeverity(log_message->severity));

    RETURN_IF_ERROR(fprintf(output_file_, ": %s\n", ToFblString(log_message->msg).c_str()));
    if (log_message->dropped_logs > 0) {
        bool log = true;
        bool found = false;
        for (DroppedLogs& dl : dropped_logs_) {
            if (dl.pid == log_message->pid) {
                found = true;
                // only update our vector when we get new dropped_logs value.
                if (dl.dropped_logs < log_message->dropped_logs) {
                    dl.dropped_logs = log_message->dropped_logs;
                } else {
                    log = false;
                }
                break;
            }
        }
        if (!found) {
            dropped_logs_.push_back(DroppedLogs{log_message->pid, log_message->dropped_logs});
        }
        if (log) {
            RETURN_IF_ERROR(fprintf(output_file_, "[%05ld.%06ld][%lu][%lu]", GetSeconds(log_message->time),
                                    GetNanoSeconds(log_message->time), log_message->pid,
                                    log_message->tid));
            RETURN_IF_ERROR(fputs("[", output_file_));
            fidl_string_t* tags = static_cast<fidl_string_t*>(log_message->tags.data);
            for (size_t i = 0; i < log_message->tags.count; ++i) {
                RETURN_IF_ERROR(fprintf(output_file_, "%s", ToFblString(tags[i]).c_str()));
                if (i < log_message->tags.count - 1) {
                    RETURN_IF_ERROR(fputs(", ", output_file_));
                }
            }
            RETURN_IF_ERROR(fputs("]", output_file_));
            RETURN_IF_ERROR(fprintf(output_file_, " WARNING: Dropped logs count:%d\n",
                                    log_message->dropped_logs));
        }
    }
    return 0;
}

zx_status_t LogExporter::Log(fidl::Message message) {
    const char* error_msg = nullptr;
    zx_status_t status = message.Decode(&fuchsia_logger_LogListenerLogRequestTable, &error_msg);
    if (status != ZX_OK) {
        fprintf(stderr, "log-listener: error: Log: %s\n", error_msg);
        return status;
    }

    fuchsia_logger_LogMessage* log_message = message.GetPayloadAs<fuchsia_logger_LogMessage>();
    if (LogMessage(log_message) < 0) {
        NotifyFileError(strerror(errno));
    }
    return ZX_OK;
}

zx_status_t LogExporter::LogMany(fidl::Message message) {
    const char* error_msg = nullptr;
    zx_status_t status = message.Decode(&fuchsia_logger_LogListenerLogManyRequestTable, &error_msg);
    if (status != ZX_OK) {
        fprintf(stderr, "log-listener: error: LogMany: %s\n", error_msg);
        return status;
    }

    fidl_vector_t* log_messages = message.GetPayloadAs<fidl_vector_t>();
    fuchsia_logger_LogMessage* msgs = static_cast<fuchsia_logger_LogMessage*>(log_messages->data);
    for (size_t i = 0; i < log_messages->count; ++i) {
        if (LogMessage(&msgs[i]) < 0) {
            NotifyFileError(strerror(errno));
            return ZX_OK;
        }
    }
    return ZX_OK;
}

void LogExporter::NotifyError(zx_status_t error) {
    channel_.reset();
    fclose(output_file_);
    output_file_ = nullptr;
    if (error_handler_) {
        error_handler_(error);
    }
}

void LogExporter::NotifyFileError(const char* error) {
    channel_.reset();
    fclose(output_file_);
    output_file_ = nullptr;
    if (file_error_handler_) {
        file_error_handler_(error);
    }
}

std::unique_ptr<LogExporter> LaunchLogExporter(const fbl::StringPiece syslog_path,
                                               ExporterLaunchError* error) {
    *error = NO_ERROR;
    fbl::String syslog_path_str = fbl::String(syslog_path.data());
    FILE* syslog_file = fopen(syslog_path_str.c_str(), "w");
    if (syslog_file == nullptr) {
        fprintf(stderr, "Error: Could not open syslog file: %s.\n", syslog_path_str.c_str());
        *error = OPEN_FILE;
        return nullptr;
    }

    // Try and connect to logger service if available. It would be only
    // available in garnet and above layer
    zx::channel logger, logger_request;
    zx_status_t status;

    status = zx::channel::create(0, &logger, &logger_request);
    if (status != ZX_OK) {
        fprintf(stderr, "LaunchLogExporter: cannot create channel for logger service: %d (%s).\n",
               status, zx_status_get_string(status));
        *error = CREATE_CHANNEL;
        return nullptr;
    }

    status = fdio_service_connect("/svc/fuchsia.logger.Log", logger_request.release());
    if (status != ZX_OK) {
        fprintf(stderr, "LaunchLogExporter: cannot connect to logger service: %d (%s).\n",
               status, zx_status_get_string(status));
        *error = CONNECT_TO_LOGGER_SERVICE;
        return nullptr;
    }

    // Create a log exporter channel and pass it to logger service.
    zx::channel listener, listener_request;
    status = zx::channel::create(0, &listener, &listener_request);
    if (status != ZX_OK) {
        fprintf(stderr, "LaunchLogExporter: cannot create channel for listener: %d (%s).\n",
               status, zx_status_get_string(status));
        *error = CREATE_CHANNEL;
        return nullptr;
    }
    fuchsia_logger_LogListenRequest req = {};
    req.hdr.ordinal = fuchsia_logger_LogListenOrdinal;
    req.log_listener = FIDL_HANDLE_PRESENT;
    zx_handle_t listener_handle = listener.release();
    status = logger.write(0, &req, sizeof(req), &listener_handle, 1);
    if (status != ZX_OK) {
        fprintf(stderr, "LaunchLogExporter: cannot pass listener to logger service: %d (%s).\n",
               status, zx_status_get_string(status));
        *error = FIDL_ERROR;
        return nullptr;
    }

    // Connect log exporter channel to object and start message loop on it.
    auto log_exporter = std::make_unique<LogExporter>(std::move(listener_request),
                                                      syslog_file);
    log_exporter->set_error_handler([](zx_status_t status) {
        if (status != ZX_ERR_CANCELED) {
            fprintf(stderr, "log exporter: Failed: %d (%s).\n",
                   status, zx_status_get_string(status));
        }
    });
    log_exporter->set_file_error_handler([](const char* error) {
        fprintf(stderr, "log exporter: Error writing to file: %s.\n", error);
    });
    status = log_exporter->StartThread();
    if (status != ZX_OK) {
        fprintf(stderr, "LaunchLogExporter: Failed to start log exporter: %d (%s).\n",
               status, zx_status_get_string(status));
        *error = START_LISTENER;
        return nullptr;
    }
    return log_exporter;
}

} // namespace runtests
