/*
 *
 *    Copyright (c) 2021 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 <nlunit-test.h>
#include <stdio.h>

#include <lib/support/BytesToHex.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CHIPPlatformMemory.h>
#include <lib/support/UnitTestContext.h>
#include <setup_payload/AdditionalDataPayloadGenerator.h>
#include <setup_payload/AdditionalDataPayloadParser.h>
#include <setup_payload/SetupPayload.h>
#include <system/SystemPacketBuffer.h>

#include <lib/support/UnitTestRegistration.h>
#include <lib/support/verhoeff/Verhoeff.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(nlTestSuite * inSuite, 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)
    {
        NL_TEST_ASSERT(inSuite, !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);
}

void TestGeneratingAdditionalDataPayloadWithoutRotatingDeviceId(nlTestSuite * inSuite, void * inContext)
{
    BitFlags<AdditionalDataFields> additionalDataFields;
    char output[kAdditionalDataPayloadLength];
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;

    NL_TEST_ASSERT(inSuite,
                   GenerateAdditionalDataPayload(inSuite, additionalDataPayloadParams, additionalDataFields, output) ==
                       CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, strcmp(output, kAdditionalDataPayloadWithoutRotatingDeviceId) == 0);
}

#if CHIP_ENABLE_ROTATING_DEVICE_ID
void TestGeneratingAdditionalDataPayloadWithRotatingDeviceId(nlTestSuite * inSuite, void * inContext)
{
    BitFlags<AdditionalDataFields> additionalDataFields;
    additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId);
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter = kLifetimeCounter;
    additionalDataPayloadParams.rotatingDeviceIdUniqueId        = ByteSpan{ kUniqueId, sizeof(kUniqueId) };

    char output[kAdditionalDataPayloadLength];
    NL_TEST_ASSERT(inSuite,
                   GenerateAdditionalDataPayload(inSuite, additionalDataPayloadParams, additionalDataFields, output) ==
                       CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, strcmp(output, kAdditionalDataPayloadWithRotatingDeviceId) == 0);
}

void TestGeneratingAdditionalDataPayloadWithRotatingDeviceIdAndMaxLifetimeCounter(nlTestSuite * inSuite, void * inContext)
{
    BitFlags<AdditionalDataFields> additionalDataFields;
    additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId);
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter = std::numeric_limits<uint16_t>::max();
    additionalDataPayloadParams.rotatingDeviceIdUniqueId        = ByteSpan{ kUniqueId, sizeof(kUniqueId) };

    char output[kAdditionalDataPayloadLength];
    NL_TEST_ASSERT(inSuite,
                   GenerateAdditionalDataPayload(inSuite, additionalDataPayloadParams, additionalDataFields, output) ==
                       CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, strcmp(output, kAdditionalDataPayloadWithRotatingDeviceIdAndMaxLifetimeCounter) == 0);
}

void TestGeneratingAdditionalDataPayloadWithRotatingDeviceIdWithNullInputs(nlTestSuite * inSuite, void * inContext)
{
    BitFlags<AdditionalDataFields> additionalDataFields;
    additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId);
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;

    char output[kAdditionalDataPayloadLength];
    NL_TEST_ASSERT(inSuite,
                   GenerateAdditionalDataPayload(inSuite, additionalDataPayloadParams, additionalDataFields, output) ==
                       CHIP_ERROR_INVALID_ARGUMENT);
}

void TestGeneratingRotatingDeviceIdAsString(nlTestSuite * inSuite, void * inContext)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    char rotatingDeviceIdHexBuffer[RotatingDeviceId::kHexMaxLength];
    size_t rotatingDeviceIdValueOutputSize = 0;
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter = kLifetimeCounter;
    additionalDataPayloadParams.rotatingDeviceIdUniqueId        = ByteSpan{ kUniqueId, sizeof(kUniqueId) };
    err = AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsHexString(
        additionalDataPayloadParams, rotatingDeviceIdHexBuffer, ArraySize(rotatingDeviceIdHexBuffer),
        rotatingDeviceIdValueOutputSize);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, strcmp(rotatingDeviceIdHexBuffer, kRotatingDeviceId) == 0);
    // Parsing out the lifetime counter value
    long lifetimeCounter;
    char lifetimeCounterStr[3];
    strncpy(lifetimeCounterStr, rotatingDeviceIdHexBuffer, 2);
    lifetimeCounterStr[2] = 0;

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

void TestGeneratingRotatingDeviceIdAsStringWithNullInputs(nlTestSuite * inSuite, void * inContext)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    char rotatingDeviceIdHexBuffer[RotatingDeviceId::kHexMaxLength];
    size_t rotatingDeviceIdValueOutputSize = 0;
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter = 0;
    additionalDataPayloadParams.rotatingDeviceIdUniqueId        = MutableByteSpan{ nullptr, sizeof(kUniqueId) };
    err = AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsHexString(
        additionalDataPayloadParams, rotatingDeviceIdHexBuffer, ArraySize(rotatingDeviceIdHexBuffer),
        rotatingDeviceIdValueOutputSize);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
}

void TestGeneratingRotatingDeviceIdWithSmallBuffer(nlTestSuite * inSuite, void * inContext)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    char rotatingDeviceIdHexBuffer[kShortRotatingIdLength];
    size_t rotatingDeviceIdValueOutputSize = 0;
    AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter = kLifetimeCounter;
    additionalDataPayloadParams.rotatingDeviceIdUniqueId        = ByteSpan{ kUniqueId, sizeof(kUniqueId) };
    err = AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsHexString(
        additionalDataPayloadParams, rotatingDeviceIdHexBuffer, ArraySize(rotatingDeviceIdHexBuffer),
        rotatingDeviceIdValueOutputSize);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
}
#endif // CHIP_ENABLE_ROTATING_DEVICE_ID

void TestParsingAdditionalDataPayloadWithRotatingDeviceId(nlTestSuite * inSuite, void * inContext)
{
    chip::SetupPayloadData::AdditionalDataPayload resultPayload;
    NL_TEST_ASSERT(inSuite,
                   ParseAdditionalDataPayload(kAdditionalDataPayloadWithRotatingDeviceId,
                                              strlen(kAdditionalDataPayloadWithRotatingDeviceId), resultPayload) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, strcmp(resultPayload.rotatingDeviceId.c_str(), kRotatingDeviceId) == 0);
}

void TestParsingAdditionalDataPayloadWithoutRotatingDeviceId(nlTestSuite * inSuite, void * inContext)
{
    chip::SetupPayloadData::AdditionalDataPayload resultPayload;
    NL_TEST_ASSERT(inSuite,
                   ParseAdditionalDataPayload(kAdditionalDataPayloadWithoutRotatingDeviceId,
                                              strlen(kAdditionalDataPayloadWithoutRotatingDeviceId),
                                              resultPayload) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, strcmp(resultPayload.rotatingDeviceId.c_str(), "") == 0);
}

void TestParsingAdditionalDataPayloadWithInvalidRotatingDeviceIdLength(nlTestSuite * inSuite, void * inContext)
{
    chip::SetupPayloadData::AdditionalDataPayload resultPayload;
    NL_TEST_ASSERT(inSuite,
                   ParseAdditionalDataPayload(kAdditionalDataPayloadWithInvalidRotatingDeviceIdLength,
                                              strlen(kAdditionalDataPayloadWithInvalidRotatingDeviceIdLength),
                                              resultPayload) == CHIP_ERROR_TLV_UNDERRUN);
}

void TestParsingAdditionalDataPayloadWithLongRotatingDeviceId(nlTestSuite * inSuite, void * inContext)
{
    chip::SetupPayloadData::AdditionalDataPayload resultPayload;
    NL_TEST_ASSERT(inSuite,
                   ParseAdditionalDataPayload(kAdditionalDataPayloadWithLongRotatingDeviceId,
                                              strlen(kAdditionalDataPayloadWithLongRotatingDeviceId),
                                              resultPayload) == CHIP_ERROR_INVALID_STRING_LENGTH);
}

void TestParsingAdditionalDataPayloadWithShortRotatingDeviceId(nlTestSuite * inSuite, void * inContext)
{
    chip::SetupPayloadData::AdditionalDataPayload resultPayload;
    NL_TEST_ASSERT(inSuite,
                   ParseAdditionalDataPayload(kAdditionalDataPayloadWithShortRotatingDeviceId,
                                              strlen(kAdditionalDataPayloadWithShortRotatingDeviceId),
                                              resultPayload) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, strcmp(resultPayload.rotatingDeviceId.c_str(), kShortRotatingDeviceId) == 0);
}

/**
 *  Test Suite that lists all the Test functions.
 */
// clang-format off
const nlTest sTests[] =
{
    NL_TEST_DEF("Test Generating Additional Data Payload without Rotatin gDevice Id", TestGeneratingAdditionalDataPayloadWithoutRotatingDeviceId),
    #if CHIP_ENABLE_ROTATING_DEVICE_ID
    NL_TEST_DEF("Test Generating Additional Data Payload with Rotating Device Id", TestGeneratingAdditionalDataPayloadWithRotatingDeviceId),
    NL_TEST_DEF("Test Generating Additional Data Payload with Rotating Device Id + Max Lifetime Counter", TestGeneratingAdditionalDataPayloadWithRotatingDeviceIdAndMaxLifetimeCounter),
    NL_TEST_DEF("Test Generating Additional Data Payload with Rotating Device Id + Null/Empty Inputs", TestGeneratingAdditionalDataPayloadWithRotatingDeviceIdWithNullInputs),
    NL_TEST_DEF("Test Generating Rotating Device Id as string", TestGeneratingRotatingDeviceIdAsString),
    NL_TEST_DEF("Test Generating Rotating Device Id as string with null/invalid inputs", TestGeneratingRotatingDeviceIdAsStringWithNullInputs),
    NL_TEST_DEF("Test Generating Rotating Device Id as string with small buffer", TestGeneratingRotatingDeviceIdWithSmallBuffer),
    #endif
    NL_TEST_DEF("Test Parsing Additional Data Payload with Rotating Device Id", TestParsingAdditionalDataPayloadWithRotatingDeviceId),
    NL_TEST_DEF("Test Parsing Additional Data Payload without Rotating Device Id", TestParsingAdditionalDataPayloadWithoutRotatingDeviceId),
    NL_TEST_DEF("Test Parsing Additional Data Payload with Invalid Rotating Device Id Length", TestParsingAdditionalDataPayloadWithInvalidRotatingDeviceIdLength),
    NL_TEST_DEF("Test Parsing Additional Data Payload with Long Rotating Device Id", TestParsingAdditionalDataPayloadWithLongRotatingDeviceId),
    NL_TEST_DEF("Test Parsing Additional Data Payload with Short Rotating Device Id", TestParsingAdditionalDataPayloadWithShortRotatingDeviceId),
    NL_TEST_SENTINEL()
};
// clang-format on

} // namespace

/**
 *  Set up the test suite.
 */
int TestAdditionalDataPayload_Setup(void * inContext)
{
    CHIP_ERROR error = chip::Platform::MemoryInit();
    if (error != CHIP_NO_ERROR)
        return FAILURE;
    return SUCCESS;
}

/**
 *  Tear down the test suite.
 */
int TestAdditionalDataPayload_Teardown(void * inContext)
{
    chip::Platform::MemoryShutdown();
    return SUCCESS;
}

/**
 *  Main
 */
int TestAdditionalDataPayload()
{
    // clang-format off
    nlTestSuite theSuite =
    {
        "chip-additional-data-payload-general-Tests",
        &sTests[0],
        TestAdditionalDataPayload_Setup,
        TestAdditionalDataPayload_Teardown
    };
    // clang-format on

    // Generate machine-readable, comma-separated value (CSV) output.
    nl_test_set_output_style(OUTPUT_CSV);

    return chip::ExecuteTestsWithoutContext(&theSuite);
}

CHIP_REGISTER_TEST_SUITE(TestAdditionalDataPayload);
