/*
 * Copyright 2023 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/private/SkAssert.h"
#include "include/private/SkMalloc.h"
#include "tests/Test.h"

#include <cstddef>
#include <cstdint>

DEF_TEST(SkFree_SafeToPassNull, reporter) {
    // This test passes by not crashing
    sk_free(nullptr);
}

DEF_TEST(SkCalloc_DataIsZeroInitializedAndWriteable, reporter) {
    constexpr size_t alloc_count = 100;

    uint8_t* bytes = (uint8_t*) sk_calloc_throw(alloc_count); // provide num bytes directly
    SkASSERT_RELEASE(bytes != nullptr);
    for (size_t i = 0; i < alloc_count; i++) {
        REPORTER_ASSERT(reporter, bytes[i] == 0);
        bytes[i] = (uint8_t)i;
    }
    sk_free(bytes);

    int32_t* ints = (int32_t*) sk_calloc_throw(alloc_count, sizeof(int32_t)); // count + elem size
    SkASSERT_RELEASE(ints != nullptr);
    for (size_t i = 0; i < alloc_count; i++) {
        REPORTER_ASSERT(reporter, ints[i] == 0);
        ints[i] = (int32_t)i;
    }
    sk_free(ints);
}

DEF_TEST(SkMalloc_DataIsWriteable, reporter) {
    constexpr size_t alloc_count = 100;

    uint8_t* bytes = (uint8_t*) sk_malloc_throw(alloc_count); // provide num bytes directly
    SkASSERT_RELEASE(bytes != nullptr);
    for (size_t i = 0; i < alloc_count; i++) {
        bytes[i] = (uint8_t)i;
    }
    sk_free(bytes);

    int32_t* ints = (int32_t*) sk_malloc_throw(alloc_count, sizeof(int32_t)); // count + elem size
    SkASSERT_RELEASE(ints != nullptr);
    for (size_t i = 0; i < alloc_count; i++) {
        ints[i] = (int32_t)i;
    }
    sk_free(ints);
}

DEF_TEST(SkRealloc_DataIsWriteableAndEventuallyFreed, reporter) {
    // Calling sk_realloc_throw with null should be treated as if it was sk_malloc_throw
    uint8_t* bytes = (uint8_t*) sk_realloc_throw(nullptr, 10);
    SkASSERT_RELEASE(bytes != nullptr);
    // Make sure those 10 bytes are writeable
    for (size_t i = 0; i < 10; i++) {
        bytes[i] = (uint8_t)i;
    }

    // Make it smaller
    bytes = (uint8_t*) sk_realloc_throw(bytes, 5);
    SkASSERT_RELEASE(bytes != nullptr);
    // Make sure those 5 bytes are still writeable and contain the previous values
    for (int i = 0; i < 5; i++) {
        REPORTER_ASSERT(reporter, bytes[i] == i, "bytes[%d] != %d", i, i);
        bytes[i] = (uint8_t)i + 17;
    }

    // Make it bigger
    bytes = (uint8_t*) sk_realloc_throw(bytes, 20, sizeof(uint8_t)); // count + elem size
    SkASSERT_RELEASE(bytes != nullptr);
    // Make sure the first 5 bytes are still writeable and contain the previous values
    for (int i = 0; i < 5; i++) {
        REPORTER_ASSERT(reporter, bytes[i] == (i + 17), "bytes[%d] != %d", i, i+17);
        bytes[i] = (uint8_t)i + 43;
    }
    // The next 15 bytes are uninitialized, so just make sure we can write to them.
    for (int i = 5; i < 20; i++) {
        bytes[i] = (uint8_t)i + 43;
    }

    // This should free the memory and return nullptr.
    bytes = (uint8_t*) sk_realloc_throw(bytes, 0);
    REPORTER_ASSERT(reporter, bytes == nullptr);
    // We run our tests with LeakSanitizer, so if bytes is *not* freed, we should see a failure.
}
