/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    All rights reserved.
 *
 *    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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <gtest/gtest.h>

#include <lib/core/CHIPCore.h>
#include <lib/core/ErrorStr.h>

using namespace chip;

#if CHIP_CONFIG_ERROR_SOURCE && !CHIP_CONFIG_SHORT_ERROR_STR

const char * CheckAndSkipSource(const char * s, const char * file, unsigned int line)
{
    size_t fileLength = strlen(file);
    EXPECT_EQ(strncmp(s, file, fileLength), 0);
    EXPECT_EQ(s[fileLength], ':');
    char * end;
    EXPECT_EQ(strtoul(&s[fileLength + 1], &end, 10), line);
    EXPECT_EQ(strncmp(end, ": ", 2), 0);
    return end + 2;
}

#define CHECK_AND_SKIP_SOURCE(s) CheckAndSkipSource((s), __FILE__, __LINE__)

#else // CHIP_CONFIG_ERROR_SOURCE && !CHIP_CONFIG_SHORT_ERROR_STR

#define CHECK_AND_SKIP_SOURCE(s) (s)

#endif // CHIP_CONFIG_ERROR_SOURCE && !CHIP_CONFIG_SHORT_ERROR_STR

static int falseFormatCalled = 0;
static bool falseFormat(char * buf, uint16_t bufSize, CHIP_ERROR err)
{
    falseFormatCalled += 1;
    return false; // means keep going
}
static int falseFormat2Called = 0;
static bool falseFormat2(char * buf, uint16_t bufSize, CHIP_ERROR err)
{
    falseFormat2Called += 1;
    return false; // means keep going
}
static int trueFormatCalled = 0;
static bool trueFormat(char * buf, uint16_t bufSize, CHIP_ERROR err)
{
    trueFormatCalled += 1;
    return true; // means I handled it
}

TEST(TestErrorStr, CheckRegisterDeregisterErrorFormatter)
{
    static ErrorFormatter falseFormatter  = { falseFormat, nullptr };
    static ErrorFormatter falseFormatter2 = { falseFormat2, nullptr };
    static ErrorFormatter trueFormatter   = { trueFormat, nullptr };

    // simple case
    RegisterErrorFormatter(&falseFormatter);
    ErrorStr(CHIP_ERROR_INTERNAL);
    EXPECT_EQ(falseFormatCalled, 1);
    // reset
    falseFormatCalled = 0;

    // re-registration should be ignored
    RegisterErrorFormatter(&falseFormatter);
    ErrorStr(CHIP_ERROR_INTERNAL);
    EXPECT_EQ(falseFormatCalled, 1);
    // reset
    falseFormatCalled = 0;

    // registration of a new handler, nobody handling anything
    RegisterErrorFormatter(&falseFormatter2);
    ErrorStr(CHIP_ERROR_INTERNAL);
    EXPECT_EQ(falseFormatCalled, 1);
    EXPECT_EQ(falseFormat2Called, 1);
    // reset
    falseFormatCalled  = 0;
    falseFormat2Called = 0;

    // registration of a true handler, gets first crack
    RegisterErrorFormatter(&trueFormatter);
    ErrorStr(CHIP_ERROR_INTERNAL);
    EXPECT_EQ(trueFormatCalled, 1);
    EXPECT_EQ(falseFormatCalled, 0);
    EXPECT_EQ(falseFormat2Called, 0);
    // reset
    trueFormatCalled = 0;

    // deregister true
    DeregisterErrorFormatter(&trueFormatter);
    ErrorStr(CHIP_ERROR_INTERNAL);
    EXPECT_EQ(trueFormatCalled, 0);
    EXPECT_EQ(falseFormatCalled, 1);
    EXPECT_EQ(falseFormat2Called, 1);

    // verify this doesn't crash
    DeregisterErrorFormatter(&trueFormatter);
}

TEST(TestErrorStr, CheckNoError)
{
    EXPECT_STREQ(CHECK_AND_SKIP_SOURCE(ErrorStr(CHIP_NO_ERROR)), CHIP_NO_ERROR_STRING);
}

TEST(TestErrorStr, CheckFormatErr)
{
#if CHIP_CONFIG_SHORT_ERROR_STR

    // TODO tests for this config

#else // CHIP_CONFIG_SHORT_ERROR_STR
    static const size_t kBufSize = 1024;
    static char buf[kBufSize];
    static const char subsys[] = "subsys";
    static const char desc[]   = "desc";

    strcpy(buf, "hi");
    // shouldn't touch the buffer
    FormatError(buf, 0, subsys, CHIP_ERROR_INTERNAL, desc);
    EXPECT_STREQ(buf, "hi");

    // guarantees null termination, doesn't touch past 1st byte
    strcpy(buf, "hi");
    FormatError(buf, 1, subsys, CHIP_ERROR_INTERNAL, desc);
    EXPECT_STREQ(buf, "");
    EXPECT_EQ(buf[1], 'i');

    // whole shebang
    FormatError(buf, kBufSize, subsys, CHIP_CORE_ERROR(1), desc);
    EXPECT_STREQ(buf, "subsys Error 0x00000001: desc");

    // skip desc
    FormatError(buf, kBufSize, subsys, CHIP_CORE_ERROR(1), nullptr);
    EXPECT_STREQ(buf, "subsys Error 0x00000001");

    // skip subsys
    FormatError(buf, kBufSize, nullptr, CHIP_CORE_ERROR(1), desc);
    EXPECT_STREQ(buf, "Error 0x00000001: desc");

    // skip both
    FormatError(buf, kBufSize, nullptr, CHIP_CORE_ERROR(1), nullptr);
    EXPECT_STREQ(buf, "Error 0x00000001");
#endif
}
