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

#include <gtest/gtest.h>

#include <app-common/zap-generated/cluster-objects.h>
#include <app/data-model/Decode.h>
#include <app/data-model/Encode.h>
#include <lib/support/jsontlv/TlvJson.h>
#include <system/SystemPacketBuffer.h>
#include <system/TLVPacketBufferBackingStore.h>

namespace {

using namespace chip::Encoding;
using namespace chip;
using namespace chip::app;

System::TLVPacketBufferBackingStore gStore;
TLV::TLVWriter gWriter;
TLV::TLVReader gReader;

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

void SetupBuf()
{
    System::PacketBufferHandle buf;

    buf = System::PacketBufferHandle::New(1024);
    gStore.Init(std::move(buf));

    gWriter.Init(gStore);
    gReader.Init(gStore);
}

CHIP_ERROR SetupReader()
{
    gReader.Init(gStore);
    return gReader.Next();
}

bool Matches(const char * referenceString, Json::Value & generatedValue)
{
    auto generatedStr = JsonToString(generatedValue);

    // Normalize the reference string to the expected compact value.
    Json::Reader reader;
    Json::Value referenceValue;
    reader.parse(referenceString, referenceValue);

    Json::FastWriter writer;
    writer.omitEndingLineFeed();
    auto compactReferenceString = writer.write(referenceValue);

    auto matches = (generatedStr == compactReferenceString);

    if (!matches)
    {
        printf("Didn't match!\n");
        printf("Reference:\n");
        printf("%s\n", compactReferenceString.c_str());

        printf("Generated:\n");
        printf("%s\n", generatedStr.c_str());
    }

    return matches;
}

template <typename T>
void EncodeAndValidate(T val, const char * expectedJsonString)
{
    CHIP_ERROR err;

    SetupBuf();

    err = DataModel::Encode(gWriter, TLV::AnonymousTag(), val);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    err = gWriter.Finalize();
    EXPECT_EQ(err, CHIP_NO_ERROR);

    err = SetupReader();
    EXPECT_EQ(err, CHIP_NO_ERROR);

    Json::Value d;
    err = TlvToJson(gReader, d);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    bool matches = Matches(expectedJsonString, d);
    EXPECT_TRUE(matches);
}

TEST_F(TestTlvJson, TestConverter)
{

    EncodeAndValidate(static_cast<uint32_t>(30),
                      "{\n"
                      "   \"value\" : 30\n"
                      "}\n");

    EncodeAndValidate(static_cast<int32_t>(-30),
                      "{\n"
                      "   \"value\" : -30\n"
                      "}\n");

    EncodeAndValidate(false,
                      "{\n"
                      "   \"value\" : false\n"
                      "}\n");

    EncodeAndValidate(true,
                      "{\n"
                      "   \"value\" : true\n"
                      "}\n");

    EncodeAndValidate(1.0,
                      "{\n"
                      "   \"value\" : 1.0\n"
                      "}\n");

    CharSpan charSpan = "hello"_span;
    EncodeAndValidate(charSpan,
                      "{\n"
                      "   \"value\" : \"hello\"\n"
                      "}\n");

    //
    // Validated using https://base64.guru/converter/encode/hex
    //
    const uint8_t byteBuf[] = { 0x01, 0x02, 0x03, 0x04, 0xff, 0xfe, 0x99, 0x88, 0xdd, 0xcd };
    ByteSpan byteSpan(byteBuf);
    EncodeAndValidate(byteSpan,
                      "{\n"
                      "   \"value\" : \"base64:AQIDBP/+mYjdzQ==\"\n"
                      "}\n");

    DataModel::Nullable<uint8_t> nullValue;
    EncodeAndValidate(nullValue,
                      "{\n"
                      "   \"value\" : null\n"
                      "}\n");

    Clusters::UnitTesting::Structs::SimpleStruct::Type structVal;
    structVal.a = 20;
    structVal.b = true;
    structVal.d = byteBuf;
    structVal.e = charSpan;
    structVal.g = 1.0;
    structVal.h = 1.0;

    EncodeAndValidate(structVal,
                      "{\n"
                      "   \"value\" : {\n"
                      "      \"0\" : 20,\n"
                      "      \"1\" : true,\n"
                      "      \"2\" : 0,\n"
                      "      \"3\" : \"base64:AQIDBP/+mYjdzQ==\",\n"
                      "      \"4\" : \"hello\",\n"
                      "      \"5\" : 0,\n"
                      "      \"6\" : 1.0,\n"
                      "      \"7\" : 1.0\n"
                      "   }\n"
                      "}\n");

    uint8_t int8uListData[] = { 1, 2, 3, 4 };
    DataModel::List<uint8_t> int8uList;

    int8uList = int8uListData;

    EncodeAndValidate(int8uList,
                      "{\n"
                      "   \"value\" : [ 1, 2, 3, 4 ]\n"
                      "}\n");

    int8uList = {};
    EncodeAndValidate(int8uList,
                      "{\n"
                      "   \"value\" : []\n"
                      "}\n");

    DataModel::Nullable<DataModel::List<uint8_t>> nullValueList;
    EncodeAndValidate(nullValueList,
                      "{\n"
                      "   \"value\" : null\n"
                      "}\n");

    Clusters::UnitTesting::Structs::SimpleStruct::Type structListData[2] = { structVal, structVal };
    DataModel::List<Clusters::UnitTesting::Structs::SimpleStruct::Type> structList;

    structList = structListData;

    EncodeAndValidate(structList,
                      "{\n"
                      "   \"value\" : [\n"
                      "      {\n"
                      "         \"0\" : 20,\n"
                      "         \"1\" : true,\n"
                      "         \"2\" : 0,\n"
                      "         \"3\" : \"base64:AQIDBP/+mYjdzQ==\",\n"
                      "         \"4\" : \"hello\",\n"
                      "         \"5\" : 0,\n"
                      "         \"6\" : 1.0,\n"
                      "         \"7\" : 1.0\n"
                      "      },\n"
                      "      {\n"
                      "         \"0\" : 20,\n"
                      "         \"1\" : true,\n"
                      "         \"2\" : 0,\n"
                      "         \"3\" : \"base64:AQIDBP/+mYjdzQ==\",\n"
                      "         \"4\" : \"hello\",\n"
                      "         \"5\" : 0,\n"
                      "         \"6\" : 1.0,\n"
                      "         \"7\" : 1.0\n"
                      "      }\n"
                      "   ]\n"
                      "}\n");
}

} // namespace
