// Copyright 2024 Google LLC
//
// 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.

#pragma once

#include "google3/host_commands.h"

#include "message_util.hpp"

#include <fmt/format.h>

#include <stdplus/raw.hpp>

#include <algorithm>
#include <chrono>
#include <condition_variable>
#include <cstdint>
#include <cstring>
#include <functional>
#include <iostream>
#include <mutex>
#include <optional>
#include <queue>
#include <thread>
#include <unordered_map>

constexpr int kTransactionBufferSize = 1024;
constexpr int kBufferReadTimeoutMs = 1000;
constexpr int kMaxReadBufferIterations = 35;
constexpr bool kDebug = false;
constexpr int kHothBufferSize = 4096;
constexpr int kRateLimiterMilliSeconds = 500;
constexpr int kTransactionTimeoutInMicroSec = 1000;
constexpr int kMaxFileSizeInBytes = 4 * 1024 * 1024; // 4 MB in bytes
constexpr int kAsyncWaitTimeInSeconds = 30;
constexpr int kHeartBeatUpperLimit = 25;
const std::string kSyslogFileNamePrefix = "/tmp/syslog_file_";

// This is required to get a read-offset that is guaranteed to be out of the
// Hoth buffer, thus clients can offset the write-buffer with a big-enough value
// and let Hoth point to the correct read-offset.
// Use the same value as the upstreamed libhoth/htool:
// https://github.com/google/libhoth/commit/e4827163741e0804f12ac96c81b8e97649be6795
constexpr uint32_t kReadOffsetTweak = 0x80000000;

namespace google
{
namespace hoth
{
namespace internal
{
enum class PublishType : uint8_t
{
    Stderr,
    File
};

/**
 * @brief Supports rate limit for a single threaded mechanism, where requests
 * are discarded when the elapsed time < rate limit time
 */
class RateLimiter
{
  public:
    explicit RateLimiter(int rateLimitInMilliseconds) :
        rateLimitInMilliseconds(rateLimitInMilliseconds)
    {
        std::chrono::hours one_day(24);
        std::chrono::steady_clock::time_point yesterday =
            std::chrono::steady_clock::now() - one_day;
        lastTimeStamp = yesterday;
    };

    bool allowedByLimiter()
    {
        auto now = std::chrono::steady_clock::now();
        auto timeElapsed = now - lastTimeStamp;
        if (timeElapsed > std::chrono::milliseconds(rateLimitInMilliseconds))
        {
            lastTimeStamp = now;
            return true;
        }
        return false;
    };

    std::chrono::steady_clock::time_point getTimeStamp()
    {
        return lastTimeStamp;
    }

  private:
    int rateLimitInMilliseconds;
    std::chrono::steady_clock::time_point lastTimeStamp;
};

class LogCollectorUtil
{
  public:
    LogCollectorUtil(RateLimiter& rateLimiter, int asyncWaitTime);

    ~LogCollectorUtil() = default;
    /**
     * @brief Generates a request for snapshotting hoth buffer
     *
     * @return request as a vector of bytes
     */
    static std::vector<uint8_t> generateSnapshotRequest();

    /**
     * @brief Generates a request for getting the snapshot of the hoth buffer
     *
     * @return request as a vector of bytes
     */
    static std::vector<uint8_t> generateGrabSnapshotRequest();

    /**
     * @brief Verifies the response header
     *
     * @return true or false (in terms of validity)
     */
    static bool isResponseValid(std::vector<uint8_t> response);

    /**
     * @brief Generates Collect Uart Request
     *
     * @param[in] channelId - Channel Id for Uart
     * @param[in] readOffset - Offset from where the buffer is to be read
     */
    static std::vector<uint8_t>
    generateCollectUartLogsRequest(uint32_t channelId, uint32_t readOffset);

    /**
     * @brief Publishes the snapshot based on publish type
     *
     * @param[in] response - Response vector
     * @param[in] publishType - Stderr or file
     * @param[in] filePathSuffix - File path name suffix if Publish type is file
     * @param[in] meta - If any meta data is to be printed in the logs
     *
     */
    static void publishSnapshot(std::vector<uint8_t> response,
                                PublishType publishType,
                                std::string_view filePathSuffix = "",
                                std::string_view meta = "");

    /**
     * @brief Generate unique request id
     *
     * @return request id
     */
    int generateRequestId();

    /**
     * @brief Gets the wait time set during initialization
     *
     * @return wait time in seconds
     */
    int getAsyncWaitTime() const;

    /**
     * @brief Current request counter
     */
    int requestCounter = 0;

    /**
     * @brief Create GetChannelWriteOffset request
     *
     * @param[in] channelId - Unique channel id
     *
     * @return request bytes for channel write offset
     */
    static std::vector<uint8_t>
    generateGetChannelWriteOffsetRequest(const uint32_t &channelId);

    /**
     * @brief Writes to file
     *
     * @param[in] data - string of data to be dumped in a file
     * @param[in] name - suffix of the file name (gets attached to prefix -
     * "syslog_file")
     */
    static void writeToFile(std::string_view data, std::string_view name);

    /**
     * @brief Sends a heartbeat once every kHeartBeatLimit when invoked
     *
     * @param[in] data - Message for the heartbeat
     */
    static void heartbeat(std::string_view message);

    /**
     * @brief Rate Limits the requests to be sent to log collector
     */
    RateLimiter rateLimiter;

    /**
     * @brief Async wait timer for uart logs
     */
    int asyncWaitTime = 0;
};

} // namespace internal
} // namespace hoth
} // namespace google
