// 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.

#include "log_collector_util.hpp"

#include <fmt/core.h>

#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

using google::hoth::internal::LogCollectorUtil;
using google::hoth::internal::RateLimiter;
using google::hoth::internal::RspHeader;

class LogCollectorUtilTest : public ::testing::Test
{
  protected:
    LogCollectorUtilTest() :
        rateLimiter(kRateLimiterMilliSeconds),
        logCollectorUtil(rateLimiter, /*async wait time in seconds*/ 1)
    {}

    RateLimiter rateLimiter;
    LogCollectorUtil logCollectorUtil;
};

TEST_F(LogCollectorUtilTest, GenerateSnapshotRequest)
{
    std::vector<uint8_t> expectedResponse = {0x03, 0x66, 0x97, 0x00,
                                             0x00, 0x00, 0x00, 0x00};
    std::vector<uint8_t> snapshotRequest =
        google::hoth::internal::LogCollectorUtil::generateSnapshotRequest();

    EXPECT_EQ(expectedResponse, snapshotRequest);
}

TEST_F(LogCollectorUtilTest, GenerateGrabSnapshotRequest)
{
    std::vector<uint8_t> expectedResponse = {0x03, 0x64, 0x98, 0x00, 0x00,
                                             0x00, 0x01, 0x00, 0x00};

    std::vector<uint8_t> grabSnapshotRequest =
        google::hoth::internal::LogCollectorUtil::generateGrabSnapshotRequest();

    EXPECT_EQ(expectedResponse, grabSnapshotRequest);
}

TEST_F(LogCollectorUtilTest, ValidResponseTest)
{
    std::vector<uint8_t> validResponse = {0x03, 0xFD, 0x00, 0x00,
                                          0x00, 0x00, 0x00, 0x00};
    bool status = google::hoth::internal::LogCollectorUtil::isResponseValid(
        validResponse);
    EXPECT_EQ(true, status);
}

TEST_F(LogCollectorUtilTest, InvalidResponseTest)
{
    RspHeader rspHeader;
    rspHeader.result = 1; // invalid response code
    std::vector<uint8_t> invalidResponse(sizeof(RspHeader));
    std::memcpy(invalidResponse.data(), &rspHeader, sizeof(RspHeader));
    bool status = google::hoth::internal::LogCollectorUtil::isResponseValid(
        invalidResponse);
    EXPECT_EQ(false, status);
}

TEST_F(LogCollectorUtilTest, RateLimiterAllow)
{
    // No rate limit time
    RateLimiter rateLimiter(0);
    LogCollectorUtil logCollectorUtil(rateLimiter,
                                      /*Async wait time in seconds*/ 1);
    bool statusFirstRequest = logCollectorUtil.rateLimiter.allowedByLimiter();
    bool statusSecondRequest = logCollectorUtil.rateLimiter.allowedByLimiter();
    EXPECT_TRUE(statusFirstRequest);
    EXPECT_TRUE(statusSecondRequest);
}

TEST_F(LogCollectorUtilTest, RateLimiterForbids)
{
    bool statusFirstRequest = logCollectorUtil.rateLimiter.allowedByLimiter();
    // send second request within 500 milliseconds
    bool statusSecondRequest = logCollectorUtil.rateLimiter.allowedByLimiter();
    EXPECT_TRUE(statusFirstRequest);
    EXPECT_FALSE(statusSecondRequest);
}

TEST_F(LogCollectorUtilTest, GenerateUniqueRequestId)
{
    int requestIdOne = logCollectorUtil.generateRequestId();
    int requestIdTwo = logCollectorUtil.generateRequestId();
    fmt::println(stderr, "{}, {}", requestIdOne, requestIdTwo);
}

TEST_F(LogCollectorUtilTest, GenerateGetChannelWriteOffsetRequest)
{
    std::vector<uint8_t> expectedRequest = {0x03, 0x53, 0x37, 0x3E, 0x00, 0x00,
                                            0x04, 0x00, 0x43, 0x55, 0x4e, 0x4b};
    std::vector<uint8_t> request = google::hoth::internal::LogCollectorUtil::
        generateGetChannelWriteOffsetRequest(0x4b4e5543);
    EXPECT_EQ(request, expectedRequest);
}

TEST_F(LogCollectorUtilTest, ParseChannelOffsetResponse)
{
    std::vector<uint8_t> writechannelOffsetResponse = {
        0x03, 0x37, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x52, 0x44, 0x11, 0x1b};

    uint32_t expectedOffset = 0x1b114452;

    EXPECT_EQ(true,
              logCollectorUtil.isResponseValid(writechannelOffsetResponse));
    struct ec_channel_status_response* channelWriteOffsetResp =
        reinterpret_cast<struct ec_channel_status_response*>(
            &writechannelOffsetResponse[sizeof(struct RspHeader)]);
    little_uint32_t writeOffset = channelWriteOffsetResp->write_offset;
    EXPECT_EQ(expectedOffset, writeOffset);
}

TEST_F(LogCollectorUtilTest, GenerateUartLogCollectorRequest)
{
    std::vector<uint8_t> expectedRequest = {
        0x03, 0x97, 0x36, 0x3e, 0x00, 0x00, 0x10, 0x00, 0x43, 0x55, 0x4e, 0x4b,
        0x52, 0x44, 0x11, 0x1b, 0x00, 0x04, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00};
    uint32_t offset = 0x1b114452;
    std::vector<uint8_t> requestGenerated = google::hoth::internal::
        LogCollectorUtil::generateCollectUartLogsRequest(0x4b4e5543, offset);
    EXPECT_EQ(expectedRequest, requestGenerated);
}

TEST_F(LogCollectorUtilTest, ParseUartLogCollectorResponse)
{
    std::vector<uint8_t> response = {
        0x03, 0x2a, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xda, 0x84, 0x30, 0x1b,
        0x78, 0x3a, 0x38, 0x0a, 0x5b, 0x4d, 0x33, 0x30, 0x2d, 0x36, 0x36, 0x36,
        0x42, 0x45, 0x43, 0x34, 0x41, 0x2d, 0x45, 0x5d, 0x20, 0x4d, 0x3a, 0x20,
        0x45, 0x52, 0x52, 0x20, 0x53, 0x4d, 0x42, 0x43, 0x4e, 0x3a, 0x33, 0x35,
        0x20, 0x0a, 0x5b, 0x4d, 0x33, 0x31, 0x2d, 0x36, 0x36, 0x36, 0x42, 0x46,
        0x45, 0x34, 0x37, 0x2d, 0x45, 0x5d, 0x20, 0x4d, 0x3a, 0x20, 0x45, 0x52,
        0x52, 0x20, 0x53, 0x4d, 0x42, 0x43, 0x4e, 0x3a, 0x33, 0x35, 0x20, 0x0a,
        0x5b, 0x4d, 0x33, 0x31, 0x2d, 0x36, 0x36, 0x36, 0x43, 0x30, 0x36, 0x30,
        0x46, 0x2d, 0x45, 0x5d, 0x20, 0x4d, 0x3a, 0x20, 0x45, 0x52, 0x52, 0x20,
        0x53, 0x4d, 0x42, 0x43, 0x4e, 0x3a, 0x33, 0x35, 0x20, 0x0a, 0x5b, 0x4d,
        0x33, 0x30, 0x2d, 0x36, 0x36, 0x36, 0x43, 0x30, 0x36, 0x31, 0x37, 0x2d,
        0x45, 0x5d, 0x20, 0x4d, 0x3a, 0x20, 0x45, 0x52, 0x52, 0x20, 0x53, 0x4d,
        0x42, 0x43, 0x4e, 0x3a, 0x33, 0x35, 0x20, 0x0a, 0x5b, 0x4d, 0x33, 0x30,
        0x2d, 0x36, 0x36, 0x36, 0x43, 0x30, 0x36, 0x33, 0x30, 0x2d, 0x4e, 0x5d,
        0x20, 0x67, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x6a, 0x5f, 0x73, 0x71, 0x65,
        0x5f, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x63, 0x74, 0x78, 0x2e, 0x74, 0x61,
        0x69, 0x6c, 0x3a, 0x31, 0x34, 0x2c, 0x20, 0x68, 0x65, 0x61, 0x64, 0x3a,
        0x31, 0x34, 0x0a, 0x5b, 0x4d, 0x33, 0x30, 0x2d, 0x36, 0x36, 0x36, 0x43,
        0x30, 0x36, 0x34, 0x32, 0x2d, 0x41, 0x5d, 0x20, 0x4d, 0x61, 0x73, 0x74,
        0x65, 0x72, 0x20, 0x41, 0x52, 0x42, 0x4c, 0x4f, 0x53, 0x54, 0x20, 0x3a,
        0x35, 0x0a, 0x5b, 0x4d, 0x33, 0x30, 0x2d, 0x36, 0x36, 0x36, 0x43, 0x30,
        0x36, 0x34, 0x32, 0x2d, 0x45, 0x5d, 0x20, 0x4d, 0x3a, 0x20, 0x45, 0x52,
        0x52, 0x3a, 0x20, 0x49, 0x4e, 0x43, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x3a,
        0x34, 0x30, 0x2c, 0x20, 0x6e, 0x4e, 0x3a, 0x20, 0x32, 0x0a, 0};

    uint32_t expectedOffset = 11038;
    std::span<const uint8_t> output = response;
    const auto& readResponseBody =
        stdplus::raw::copyFrom<ec_channel_read_response>(output);
    uint32_t readOffset = readResponseBody.offset +
                          (output.size() - sizeof(ec_channel_read_response));
    EXPECT_EQ(expectedOffset, readOffset);
}
