/*
 *
 *    Copyright (c) 2021-2022 Project CHIP Authors
 *
 *    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.
 */

/**
 *    @file
 *      This file implements a unit test suite for the additional payload generation
 *      code functionality.
 *
 */

#include <math.h>
#include <memory>
#include <stdio.h>

#include <gtest/gtest.h>

#include <lib/core/StringBuilderAdapters.h>
#include <lib/support/BytesToHex.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/CHIPPlatformMemory.h>
#include <lib/support/verhoeff/Verhoeff.h>
#include <setup_payload/AdditionalDataPayloadGenerator.h>
#include <setup_payload/AdditionalDataPayloadParser.h>
#include <setup_payload/SetupPayload.h>
#include <system/SystemPacketBuffer.h>

using namespace chip;

namespace {

constexpr char kAdditionalDataPayloadWithoutRotatingDeviceId[]           = "1518";
constexpr char kAdditionalDataPayloadWithRotatingDeviceId[]              = "153000120A00D00561E77A68A9FD975057375B9283A818";
constexpr char kAdditionalDataPayloadWithInvalidRotatingDeviceIdLength[] = "153000FF0A001998AB7130E38B7E9A401CFE9F7B79AF18";
constexpr char kAdditionalDataPayloadWithLongRotatingDeviceId[]          = "153000130A00191998AB7130E38B7E9A401CFE9F7B79AF18";
constexpr char kAdditionalDataPayloadWithShortRotatingDeviceId[]         = "153000110A001998AB7130E38B7E9A401CFE9F7B7918";
constexpr char kRotatingDeviceId[]                                       = "0A00D00561E77A68A9FD975057375B9283A8";
constexpr char kShortRotatingDeviceId[]                                  = "0A001998AB7130E38B7E9A401CFE9F7B79";
constexpr uint16_t kAdditionalDataPayloadLength                          = 51;
#if CHIP_ENABLE_ROTATING_DEVICE_ID
constexpr uint8_t kUniqueId[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
constexpr char kAdditionalDataPayloadWithRotatingDeviceIdAndMaxLifetimeCounter[] = "15300012FFFF8BEA0C775F001981365D6362E1C0665A18";
constexpr uint16_t kLifetimeCounter                                              = 10;
constexpr uint16_t kShortRotatingIdLength                                        = 5;
#endif // CHIP_ENABLE_ROTATING_DEVICE_ID

CHIP_ERROR GenerateAdditionalDataPayload(AdditionalDataPayloadGeneratorParams & additionalDataPayloadParams,
                                         BitFlags<AdditionalDataFields> additionalDataFields, char * additionalDataPayloadOutput)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    chip::System::PacketBufferHandle bufferHandle;

    err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(additionalDataPayloadParams, bufferHandle,
                                                                         additionalDataFields);
    if (err == CHIP_NO_ERROR)
    {
        EXPECT_FALSE(bufferHandle.IsNull());
    }
    else
    {
        return err;
    }
    char output[kAdditionalDataPayloadLength];
    err = chip::Encoding::BytesToUppercaseHexString(bufferHandle->Start(), bufferHandle->DataLength(), output, ArraySize(output));

    if (err == CHIP_NO_ERROR)
    {
        memmove(additionalDataPayloadOutput, output, kAdditionalDataPayloadLength);
    }
    return err;
}

CHIP_ERROR ParseAdditionalDataPayload(const char * additionalDataPayload, size_t additionalDataPayloadLength,
                                      chip::SetupPayloadData::AdditionalDataPayload & outPayload)
{
    if (additionalDataPayloadLength % 2 != 0)
    {
        return CHIP_ERROR_INVALID_STRING_LENGTH;
    }
    size_t additionalDataPayloadBytesLength = additionalDataPayloadLength / 2;
    std::unique_ptr<uint8_t[]> additionalDataPayloadBytes(new uint8_t[additionalDataPayloadBytesLength]);
    size_t bufferSize = chip::Encoding::HexToBytes(additionalDataPayload, additionalDataPayloadLength,
                                                   additionalDataPayloadBytes.get(), additionalDataPayloadBytesLength);
    return AdditionalDataPayloadParser(additionalDataPayloadBytes.get(), bufferSize).populatePayload(outPayload);
}

class TestAdditionalDataPayload : public ::testing::Test
{
public:
    static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); }
    static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); }
};

TEST_F(TestAdditionalDataPayload, TestGeneratingAdditionalDataPayloadWithoutRotatingDeviceId)
{
    BitFlags<AdditionalDataFields> additionalDataFields;
    char output[kAdditionalDataPayloadLength];
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;

    EXPECT_EQ(GenerateAdditionalDataPayload(additionalDataPayloadParams, additionalDataFields, output), CHIP_NO_ERROR);
    EXPECT_STREQ(output, kAdditionalDataPayloadWithoutRotatingDeviceId);
}

#if CHIP_ENABLE_ROTATING_DEVICE_ID
TEST_F(TestAdditionalDataPayload, TestGeneratingAdditionalDataPayloadWithRotatingDeviceId)
{
    BitFlags<AdditionalDataFields> additionalDataFields;
    additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId);
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter = kLifetimeCounter;
    additionalDataPayloadParams.rotatingDeviceIdUniqueId        = ByteSpan(kUniqueId);

    char output[kAdditionalDataPayloadLength];
    EXPECT_EQ(GenerateAdditionalDataPayload(additionalDataPayloadParams, additionalDataFields, output), CHIP_NO_ERROR);
    EXPECT_STREQ(output, kAdditionalDataPayloadWithRotatingDeviceId);
}

TEST_F(TestAdditionalDataPayload, TestGeneratingAdditionalDataPayloadWithRotatingDeviceIdAndMaxLifetimeCounter)
{
    BitFlags<AdditionalDataFields> additionalDataFields;
    additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId);
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter = std::numeric_limits<uint16_t>::max();
    additionalDataPayloadParams.rotatingDeviceIdUniqueId        = ByteSpan(kUniqueId);

    char output[kAdditionalDataPayloadLength];
    EXPECT_EQ(GenerateAdditionalDataPayload(additionalDataPayloadParams, additionalDataFields, output), CHIP_NO_ERROR);
    EXPECT_STREQ(output, kAdditionalDataPayloadWithRotatingDeviceIdAndMaxLifetimeCounter);
}

TEST_F(TestAdditionalDataPayload, TestGeneratingAdditionalDataPayloadWithRotatingDeviceIdWithNullInputs)
{
    BitFlags<AdditionalDataFields> additionalDataFields;
    additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId);
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;

    char output[kAdditionalDataPayloadLength];
    EXPECT_EQ(GenerateAdditionalDataPayload(additionalDataPayloadParams, additionalDataFields, output),
              CHIP_ERROR_INVALID_ARGUMENT);
}

TEST_F(TestAdditionalDataPayload, TestGeneratingRotatingDeviceIdAsString)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    char rotatingDeviceIdHexBuffer[RotatingDeviceId::kHexMaxLength];
    size_t rotatingDeviceIdValueOutputSize = 0;
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter = kLifetimeCounter;
    additionalDataPayloadParams.rotatingDeviceIdUniqueId        = ByteSpan(kUniqueId);
    err = AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsHexString(
        additionalDataPayloadParams, rotatingDeviceIdHexBuffer, ArraySize(rotatingDeviceIdHexBuffer),
        rotatingDeviceIdValueOutputSize);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_STREQ(rotatingDeviceIdHexBuffer, kRotatingDeviceId);
    // Parsing out the lifetime counter value
    long lifetimeCounter;
    char lifetimeCounterStr[3];
    Platform::CopyString(lifetimeCounterStr, rotatingDeviceIdHexBuffer);

    char * parseEnd;
    lifetimeCounter = strtol(lifetimeCounterStr, &parseEnd, 16);
    EXPECT_EQ(lifetimeCounter, kLifetimeCounter);
}

TEST_F(TestAdditionalDataPayload, TestGeneratingRotatingDeviceIdAsStringWithNullInputs)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    char rotatingDeviceIdHexBuffer[RotatingDeviceId::kHexMaxLength];
    size_t rotatingDeviceIdValueOutputSize = 0;
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter = 0;
    additionalDataPayloadParams.rotatingDeviceIdUniqueId        = ByteSpan();
    err = AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsHexString(
        additionalDataPayloadParams, rotatingDeviceIdHexBuffer, ArraySize(rotatingDeviceIdHexBuffer),
        rotatingDeviceIdValueOutputSize);
    EXPECT_EQ(err, CHIP_ERROR_INVALID_ARGUMENT);
}

TEST_F(TestAdditionalDataPayload, TestGeneratingRotatingDeviceIdWithSmallBuffer)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    char rotatingDeviceIdHexBuffer[kShortRotatingIdLength];
    size_t rotatingDeviceIdValueOutputSize = 0;
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter = kLifetimeCounter;
    additionalDataPayloadParams.rotatingDeviceIdUniqueId        = ByteSpan(kUniqueId);
    err = AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsHexString(
        additionalDataPayloadParams, rotatingDeviceIdHexBuffer, ArraySize(rotatingDeviceIdHexBuffer),
        rotatingDeviceIdValueOutputSize);
    EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);
}
#endif // CHIP_ENABLE_ROTATING_DEVICE_ID

TEST_F(TestAdditionalDataPayload, TestParsingAdditionalDataPayloadWithRotatingDeviceId)
{
    chip::SetupPayloadData::AdditionalDataPayload resultPayload;
    EXPECT_EQ(ParseAdditionalDataPayload(kAdditionalDataPayloadWithRotatingDeviceId,
                                         strlen(kAdditionalDataPayloadWithRotatingDeviceId), resultPayload),
              CHIP_NO_ERROR);
    EXPECT_STREQ(resultPayload.rotatingDeviceId.c_str(), kRotatingDeviceId);
}

TEST_F(TestAdditionalDataPayload, TestParsingAdditionalDataPayloadWithoutRotatingDeviceId)
{
    chip::SetupPayloadData::AdditionalDataPayload resultPayload;
    EXPECT_EQ(ParseAdditionalDataPayload(kAdditionalDataPayloadWithoutRotatingDeviceId,
                                         strlen(kAdditionalDataPayloadWithoutRotatingDeviceId), resultPayload),
              CHIP_NO_ERROR);
    EXPECT_STREQ(resultPayload.rotatingDeviceId.c_str(), "");
}

TEST_F(TestAdditionalDataPayload, TestParsingAdditionalDataPayloadWithInvalidRotatingDeviceIdLength)
{
    chip::SetupPayloadData::AdditionalDataPayload resultPayload;
    EXPECT_EQ(ParseAdditionalDataPayload(kAdditionalDataPayloadWithInvalidRotatingDeviceIdLength,
                                         strlen(kAdditionalDataPayloadWithInvalidRotatingDeviceIdLength), resultPayload),
              CHIP_ERROR_TLV_UNDERRUN);
}

TEST_F(TestAdditionalDataPayload, TestParsingAdditionalDataPayloadWithLongRotatingDeviceId)
{
    chip::SetupPayloadData::AdditionalDataPayload resultPayload;
    EXPECT_EQ(ParseAdditionalDataPayload(kAdditionalDataPayloadWithLongRotatingDeviceId,
                                         strlen(kAdditionalDataPayloadWithLongRotatingDeviceId), resultPayload),
              CHIP_ERROR_INVALID_STRING_LENGTH);
}

TEST_F(TestAdditionalDataPayload, TestParsingAdditionalDataPayloadWithShortRotatingDeviceId)
{
    chip::SetupPayloadData::AdditionalDataPayload resultPayload;
    EXPECT_EQ(ParseAdditionalDataPayload(kAdditionalDataPayloadWithShortRotatingDeviceId,
                                         strlen(kAdditionalDataPayloadWithShortRotatingDeviceId), resultPayload),
              CHIP_NO_ERROR);
    EXPECT_STREQ(resultPayload.rotatingDeviceId.c_str(), kShortRotatingDeviceId);
}

} // namespace
