/*
 *    Copyright (c) 2022 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 <cstring>

#include <lib/core/CHIPError.h>
#include <lib/core/CHIPPersistentStorageDelegate.h>
#include <lib/support/logging/CHIPLogging.h>

#include "PersistentStorageAudit.h"

#ifdef NL_TEST_ASSERT
#undef NL_TEST_ASSERT
#endif

#define NL_TEST_ASSERT(inSuite, inCondition)                                                                                       \
    do                                                                                                                             \
    {                                                                                                                              \
        (inSuite)->performedAssertions += 1;                                                                                       \
                                                                                                                                   \
        if (!(inCondition))                                                                                                        \
        {                                                                                                                          \
            ChipLogError(Automation, "%s:%u: assertion failed: \"%s\"", __FILE__, __LINE__, #inCondition);                         \
            (inSuite)->failedAssertions += 1;                                                                                      \
            (inSuite)->flagError = true;                                                                                           \
        }                                                                                                                          \
    } while (0)

namespace chip {
namespace audit {

// The following test is a copy of `src/lib/support/tests/TestTestPersistentStorageDelegate.cpp` 's
// `TestBasicApi()` test. It has to be copied since we currently are not setup to
// run on-device unit tests at large on all embedded platforms part of the SDK.
bool ExecutePersistentStorageApiAudit(PersistentStorageDelegate & storage)
{
    struct fakeTestSuite
    {
        int performedAssertions = 0;
        int failedAssertions    = 0;
        bool flagError          = false;
    } theSuite;
    auto * inSuite = &theSuite;

    const char * kLongKeyString = "aKeyThatIsExactlyMaxKeyLengthhhh";
    // Start fresh.
    (void) storage.SyncDeleteKeyValue("roboto");
    (void) storage.SyncDeleteKeyValue("key2");
    (void) storage.SyncDeleteKeyValue("key3");
    (void) storage.SyncDeleteKeyValue("key4");
    (void) storage.SyncDeleteKeyValue("keyDOES_NOT_EXIST");
    (void) storage.SyncDeleteKeyValue(kLongKeyString);

    // ========== Start of actual audit from TestTestPersistentStorageDelegate.cpp =========

    uint8_t buf[16];
    const uint16_t actualSizeOfBuf = static_cast<uint16_t>(sizeof(buf));
    uint16_t size                  = actualSizeOfBuf;

    // Key not there
    CHIP_ERROR err;
    memset(&buf[0], 0, sizeof(buf));
    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
    NL_TEST_ASSERT(inSuite, size == actualSizeOfBuf);

    err = storage.SyncDeleteKeyValue("roboto");
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);

    // Add basic key, read it back, erase it
    const char * kStringValue1 = "abcd";
    err                        = storage.SyncSetKeyValue("roboto", kStringValue1, static_cast<uint16_t>(strlen(kStringValue1)));
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    memset(&buf[0], 0, sizeof(buf));
    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, size == strlen(kStringValue1));
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue1, strlen(kStringValue1)));

    err = storage.SyncDeleteKeyValue("roboto");
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    memset(&buf[0], 0, sizeof(buf));
    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
    NL_TEST_ASSERT(inSuite, size == actualSizeOfBuf);

    // Validate adding 2 different keys
    const char * kStringValue2 = "0123abcd";
    const char * kStringValue3 = "cdef89";
    err                        = storage.SyncSetKeyValue("key2", kStringValue2, static_cast<uint16_t>(strlen(kStringValue2)));
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    err = storage.SyncSetKeyValue("key3", kStringValue3, static_cast<uint16_t>(strlen(kStringValue3)));
    NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist("key3"));
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    // Read them back

    uint8_t all_zeroes[sizeof(buf)];
    memset(&all_zeroes[0], 0, sizeof(all_zeroes));

    memset(&buf[0], 0, sizeof(buf));
    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue("key2", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, size == strlen(kStringValue2));
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue2, strlen(kStringValue2)));
    // Make sure that there was no buffer overflow during SyncGetKeyValue
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));

    memset(&buf[0], 0, sizeof(buf));
    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue("key3", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, size == strlen(kStringValue3));
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue3, strlen(kStringValue3)));
    // Make sure that there was no buffer overflow during SyncGetKeyValue
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));

    // Read providing too small a buffer. Data read up to `size` and nothing more.
    memset(&buf[0], 0, sizeof(buf));
    size                               = static_cast<uint16_t>(strlen(kStringValue2) - 1);
    uint16_t sizeBeforeGetKeyValueCall = size;
    err                                = storage.SyncGetKeyValue("key2", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
    NL_TEST_ASSERT(inSuite, size == sizeBeforeGetKeyValueCall);
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue2, size));
    // Make sure that there was no buffer overflow during SyncGetKeyValue
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));

    // Read in too small a buffer, which is nullptr and size == 0: check CHIP_ERROR_BUFFER_TOO_SMALL is given.
    memset(&buf[0], 0, sizeof(buf));
    size                      = 0;
    sizeBeforeGetKeyValueCall = size;
    err                       = storage.SyncGetKeyValue("key2", nullptr, size);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
    NL_TEST_ASSERT(inSuite, size != strlen(kStringValue2));
    NL_TEST_ASSERT(inSuite, size == sizeBeforeGetKeyValueCall);
    // Just making sure that implementation doesn't hold onto reference of previous destination buffer when
    // nullptr is provided.
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));

    // Read in too small a buffer, which is nullptr and size != 0: error
    size                      = static_cast<uint16_t>(strlen(kStringValue2) - 1);
    sizeBeforeGetKeyValueCall = size;
    err                       = storage.SyncGetKeyValue("key2", nullptr, size);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
    NL_TEST_ASSERT(inSuite, size == sizeBeforeGetKeyValueCall);
    // Just making sure that implementation doesn't hold onto reference of previous destination buffer when
    // nullptr is provided.
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));

    // When key not found, size is not touched.
    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue("keyDOES_NOT_EXIST", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
    NL_TEST_ASSERT(inSuite, actualSizeOfBuf == size);
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));

    size = 0;
    err  = storage.SyncGetKeyValue("keyDOES_NOT_EXIST", nullptr, size);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
    NL_TEST_ASSERT(inSuite, 0 == size);
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));

    // Even when key not found, cannot pass nullptr with size != 0.
    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue("keyDOES_NOT_EXIST", nullptr, size);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
    NL_TEST_ASSERT(inSuite, actualSizeOfBuf == size);
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], size));

    // Attempt an empty key write with either nullptr or zero size works
    err = storage.SyncSetKeyValue("key2", kStringValue2, 0);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist("key2"));

    size = 0;
    err  = storage.SyncGetKeyValue("key2", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, size == 0);

    size = 0;
    err  = storage.SyncGetKeyValue("key2", nullptr, size);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, size == 0);

    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue("key2", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, size == 0);

    err = storage.SyncSetKeyValue("key2", nullptr, 0);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist("key2"));

    size = 0;
    err  = storage.SyncGetKeyValue("key2", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, size == 0);

    // Failure to set key if buffer is nullptr and size != 0
    size = 10;
    err  = storage.SyncSetKeyValue("key4", nullptr, size);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
    NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist("key4"));

    // Can delete empty key
    err = storage.SyncDeleteKeyValue("key2");
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist("key2"));

    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue("key2", &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
    NL_TEST_ASSERT(inSuite, size == actualSizeOfBuf);
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], size));

    // Using key and value with base64 symbols
    const char * kBase64SymbolsKey   = "key+/=";
    const char * kBase64SymbolValues = "value+/=";
    err = storage.SyncSetKeyValue(kBase64SymbolsKey, kBase64SymbolValues, static_cast<uint16_t>(strlen(kBase64SymbolValues)));
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    memset(&buf[0], 0, sizeof(buf));
    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue(kBase64SymbolsKey, &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, size == strlen(kBase64SymbolValues));
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kBase64SymbolValues, strlen(kBase64SymbolValues)));
    // Make sure that there was no buffer overflow during SyncGetKeyValue
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));

    err = storage.SyncDeleteKeyValue(kBase64SymbolsKey);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist(kBase64SymbolsKey));

    // Try using key that is a size that equals PersistentStorageDelegate::kKeyLengthMax
    char longKeyString[PersistentStorageDelegate::kKeyLengthMax + 1];
    memset(&longKeyString, 'X', PersistentStorageDelegate::kKeyLengthMax);
    longKeyString[sizeof(longKeyString) - 1] = '\0';
    // strlen() is not compile time so we just have this runtime assert that should aways pass as a sanity check.
    NL_TEST_ASSERT(inSuite, strlen(longKeyString) == PersistentStorageDelegate::kKeyLengthMax);

    err = storage.SyncSetKeyValue(longKeyString, kStringValue2, static_cast<uint16_t>(strlen(kStringValue2)));
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    memset(&buf[0], 0, sizeof(buf));
    size = actualSizeOfBuf;
    err  = storage.SyncGetKeyValue(longKeyString, &buf[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, size == strlen(kStringValue2));
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue2, strlen(kStringValue2)));
    // Make sure that there was no buffer overflow during SyncGetKeyValue
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));

    NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist(longKeyString));

    err = storage.SyncDeleteKeyValue(longKeyString);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist(longKeyString));

    constexpr size_t kMaxCHIPCertLength = 400; // From credentials/CHIPCert.h and spec
    uint8_t largeBuffer[kMaxCHIPCertLength];
    memset(&largeBuffer, 'X', sizeof(largeBuffer));
    uint8_t largeBufferForCheck[sizeof(largeBuffer)];
    memcpy(largeBufferForCheck, largeBuffer, sizeof(largeBuffer));

    err = storage.SyncSetKeyValue(longKeyString, largeBuffer, static_cast<uint16_t>(sizeof(largeBuffer)));
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    memset(&largeBuffer, 0, sizeof(largeBuffer));
    size = static_cast<uint16_t>(sizeof(largeBuffer));
    err  = storage.SyncGetKeyValue(longKeyString, &largeBuffer[0], size);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, size == static_cast<uint16_t>(sizeof(largeBuffer)));
    NL_TEST_ASSERT(inSuite, 0 == memcmp(&largeBuffer, largeBufferForCheck, sizeof(largeBuffer)));

    err = storage.SyncDeleteKeyValue(longKeyString);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    // Cleaning up
    (void) storage.SyncDeleteKeyValue("roboto");
    (void) storage.SyncDeleteKeyValue("key2");
    (void) storage.SyncDeleteKeyValue("key3");
    (void) storage.SyncDeleteKeyValue("key4");
    (void) storage.SyncDeleteKeyValue(kBase64SymbolsKey);
    (void) storage.SyncDeleteKeyValue(kLongKeyString);

    // ========== End of code from TestTestPersistentStorageDelegate.cpp =========
    if (inSuite->flagError)
    {
        ChipLogError(Automation,
                     "==== PersistentStorageDelegate API audit: FAILED: %d/%d failed assertions ====", inSuite->failedAssertions,
                     inSuite->performedAssertions);
        return false;
    }

    ChipLogError(Automation, "==== PersistentStorageDelegate API audit: SUCCESS ====");
    return true;
}

bool ExecutePersistentStorageLoadTestAudit(PersistentStorageDelegate & storage)
{
    (void) storage;
    ChipLogError(Automation, "==== PersistentStorageDelegate load test audit: SUCCESS ====");
    return true;
}

} // namespace audit
} // namespace chip
