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

#include "include/core/SkData.h"
#include "include/core/SkDataTable.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/private/SkMalloc.h"
#include "src/core/SkOSFile.h"
#include "src/utils/SkOSPath.h"
#include "tests/Test.h"

#include <array>
#include <cstdio>
#include <cstring>

static void test_is_equal(skiatest::Reporter* reporter,
                          const SkDataTable* a, const SkDataTable* b) {
    REPORTER_ASSERT(reporter, a->count() == b->count());
    for (int i = 0; i < a->count(); ++i) {
        size_t sizea, sizeb;
        const void* mema = a->at(i, &sizea);
        const void* memb = b->at(i, &sizeb);
        REPORTER_ASSERT(reporter, sizea == sizeb);
        REPORTER_ASSERT(reporter, !memcmp(mema, memb, sizea));
    }
}

static void test_datatable_is_empty(skiatest::Reporter* reporter, SkDataTable* table) {
    REPORTER_ASSERT(reporter, table->isEmpty());
    REPORTER_ASSERT(reporter, 0 == table->count());
}

static void test_emptytable(skiatest::Reporter* reporter) {
    sk_sp<SkDataTable> table0(SkDataTable::MakeEmpty());
    sk_sp<SkDataTable> table1(SkDataTable::MakeCopyArrays(nullptr, nullptr, 0));
    sk_sp<SkDataTable> table2(SkDataTable::MakeCopyArray(nullptr, 0, 0));
    sk_sp<SkDataTable> table3(SkDataTable::MakeArrayProc(nullptr, 0, 0, nullptr, nullptr));

    test_datatable_is_empty(reporter, table0.get());
    test_datatable_is_empty(reporter, table1.get());
    test_datatable_is_empty(reporter, table2.get());
    test_datatable_is_empty(reporter, table3.get());

    test_is_equal(reporter, table0.get(), table1.get());
    test_is_equal(reporter, table0.get(), table2.get());
    test_is_equal(reporter, table0.get(), table3.get());
}

static void test_simpletable(skiatest::Reporter* reporter) {
    const int idata[] = { 1, 4, 9, 16, 25, 63 };
    int icount = std::size(idata);
    sk_sp<SkDataTable> itable(SkDataTable::MakeCopyArray(idata, sizeof(idata[0]), icount));
    REPORTER_ASSERT(reporter, itable->count() == icount);
    for (int i = 0; i < icount; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, sizeof(int) == itable->atSize(i));
        REPORTER_ASSERT(reporter, *itable->atT<int>(i, &size) == idata[i]);
        REPORTER_ASSERT(reporter, sizeof(int) == size);
    }
}

static void test_vartable(skiatest::Reporter* reporter) {
    const char* str[] = {
        "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
    };
    int count = std::size(str);
    size_t sizes[std::size(str)];
    for (int i = 0; i < count; ++i) {
        sizes[i] = strlen(str[i]) + 1;
    }

    sk_sp<SkDataTable> table(SkDataTable::MakeCopyArrays((const void*const*)str, sizes, count));

    REPORTER_ASSERT(reporter, table->count() == count);
    for (int i = 0; i < count; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, table->atSize(i) == sizes[i]);
        REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
                                          str[i]));
        REPORTER_ASSERT(reporter, size == sizes[i]);

        const char* s = table->atStr(i);
        REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
    }
}

static void test_globaltable(skiatest::Reporter* reporter) {
    static const int gData[] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
    };
    int count = std::size(gData);

    sk_sp<SkDataTable> table(
        SkDataTable::MakeArrayProc(gData, sizeof(gData[0]), count, nullptr, nullptr));

    REPORTER_ASSERT(reporter, table->count() == count);
    for (int i = 0; i < count; ++i) {
        size_t size;
        REPORTER_ASSERT(reporter, table->atSize(i) == sizeof(int));
        REPORTER_ASSERT(reporter, *table->atT<const char>(i, &size) == i);
        REPORTER_ASSERT(reporter, sizeof(int) == size);
    }
}

DEF_TEST(DataTable, reporter) {
    test_emptytable(reporter);
    test_simpletable(reporter);
    test_vartable(reporter);
    test_globaltable(reporter);
}

static void* gGlobal;

static void delete_int_proc(const void* ptr, void* context) {
    const int* data = (const int*)ptr;
    SkASSERT(context == gGlobal);
    delete[] data;
}

static void assert_len(skiatest::Reporter* reporter, const sk_sp<SkData>& ref, size_t len) {
    REPORTER_ASSERT(reporter, ref->size() == len);
}

static void assert_data(skiatest::Reporter* reporter, const sk_sp<SkData>& ref,
                        const void* data, size_t len) {
    REPORTER_ASSERT(reporter, ref->size() == len);
    REPORTER_ASSERT(reporter, !memcmp(ref->data(), data, len));
}

static void test_cstring(skiatest::Reporter* reporter) {
    const char str[] = "Hello world";
    size_t     len = strlen(str);

    sk_sp<SkData> r0(SkData::MakeWithCopy(str, len + 1));
    sk_sp<SkData> r1(SkData::MakeWithCString(str));

    REPORTER_ASSERT(reporter, r0->equals(r1.get()));

    sk_sp<SkData> r2(SkData::MakeWithCString(nullptr));
    REPORTER_ASSERT(reporter, 1 == r2->size());
    REPORTER_ASSERT(reporter, 0 == *r2->bytes());
}

static void test_files(skiatest::Reporter* reporter) {
    SkString tmpDir = skiatest::GetTmpDir();
    if (tmpDir.isEmpty()) {
        return;
    }

    SkString path = SkOSPath::Join(tmpDir.c_str(), "data_test");

    const char s[] = "abcdefghijklmnopqrstuvwxyz";
    {
        SkFILEWStream writer(path.c_str());
        if (!writer.isValid()) {
            ERRORF(reporter, "Failed to create tmp file %s\n", path.c_str());
            return;
        }
        writer.write(s, 26);
    }

    FILE* file = sk_fopen(path.c_str(), kRead_SkFILE_Flag);
    sk_sp<SkData> r1(SkData::MakeFromFILE(file));
    REPORTER_ASSERT(reporter, r1.get() != nullptr);
    REPORTER_ASSERT(reporter, r1->size() == 26);
    REPORTER_ASSERT(reporter, strncmp(reinterpret_cast<const char*>(r1->data()), s, 26) == 0);

    int fd = sk_fileno(file);
    sk_sp<SkData> r2(SkData::MakeFromFD(fd));
    REPORTER_ASSERT(reporter, r2.get() != nullptr);
    REPORTER_ASSERT(reporter, r2->size() == 26);
    REPORTER_ASSERT(reporter, strncmp(reinterpret_cast<const char*>(r2->data()), s, 26) == 0);
}

template <typename T> bool operator==(SkSpan<T> a, SkSpan<T> b) {
    return a.size() == b.size() && a.data() == b.data();
}
template <typename T> bool operator!=(SkSpan<T> a, SkSpan<T> b) {
    return !(a == b);
}

template <typename T> bool deep_equal(SkSpan<T> a, SkSpan<T> b) {
    if (a.size() != b.size()) {
        return false;
    }
    return (a.size() == 0) || (memcmp(a.data(), b.data(), a.size()) == 0);
}

static void test_subsets(skiatest::Reporter* reporter) {
    uint8_t array[] = {1, 2, 3, 4};
    auto src = SkData::MakeWithoutCopy(array, sizeof(array));

    struct Subset {
        size_t offset, length;
    };

    const Subset bad_subsets[] = {
        {5, 0}, {4, 2}, {0, 5}, {3, 2},
    };
    for (auto s : bad_subsets) {
        REPORTER_ASSERT(reporter, src->shareSubset(s.offset, s.length) == nullptr);
        REPORTER_ASSERT(reporter, src->copySubset(s.offset, s.length) == nullptr);
    }

    const Subset empty_subsets[] = {
        {0, 0}, {2, 0}, {4, 0},
    };
    for (auto s : empty_subsets) {
        REPORTER_ASSERT(reporter, src->shareSubset(s.offset, s.length)->empty());
        REPORTER_ASSERT(reporter, src->copySubset(s.offset, s.length)->empty());
    }

    auto assert_shared = [reporter](sk_sp<const SkData> data, SkSpan<const uint8_t> src) {
        REPORTER_ASSERT(reporter, data->byteSpan() == src);
    };
    auto assert_copied = [reporter](sk_sp<const SkData> data, SkSpan<const uint8_t> src) {
        REPORTER_ASSERT(reporter, data->byteSpan() != src);
        REPORTER_ASSERT(reporter, deep_equal(data->byteSpan(), src));
    };

    const Subset nonempty_subsets[] = {
        {0, 4}, {2, 2}, {0, 2}, {1, 2},
    };
    for (auto s : nonempty_subsets) {
        const auto srcSpan = src->byteSpan().subspan(s.offset, s.length);
        assert_shared(src->shareSubset(s.offset, s.length), srcSpan);
        assert_copied(src->copySubset(s.offset, s.length),  srcSpan);
    }
}

static void test_copies(skiatest::Reporter* reporter) {
    int32_t array[10];
    for (int i = 0; i < 10; ++i) array[i] = i;

    auto d = SkData::MakeWithCopy(array, sizeof(array));
    REPORTER_ASSERT(reporter, d->size() == sizeof(array));
    REPORTER_ASSERT(reporter, memcmp(array, d->data(), sizeof(array)) == 0);

    auto d1 = d->shareSubset(8, 16);    // 2, 3, 4, 5
    REPORTER_ASSERT(reporter, d1->size() == 16);
    REPORTER_ASSERT(reporter, d1->bytes() == d->bytes() + 8);

    auto d2 = d->copySubset(8, 16);
    REPORTER_ASSERT(reporter, d2->size() == 16);
    REPORTER_ASSERT(reporter, memcmp(d2->data(), &array[2], d2->size()) == 0);

    REPORTER_ASSERT(reporter, *d == *d);
    REPORTER_ASSERT(reporter, *d != *d1);
    REPORTER_ASSERT(reporter, *d1 == *d2);
}

DEF_TEST(Data, reporter) {
    const char* str = "We the people, in order to form a more perfect union.";
    const int N = 10;

    sk_sp<SkData> r0(SkData::MakeEmpty());
    sk_sp<SkData> r1(SkData::MakeWithCopy(str, strlen(str)));
    sk_sp<SkData> r2(SkData::MakeWithProc(new int[N], N*sizeof(int), delete_int_proc, gGlobal));
    sk_sp<SkData> r3(SkData::MakeSubset(r1.get(), 7, 6));

    assert_len(reporter, r0, 0);
    assert_len(reporter, r1, strlen(str));
    assert_len(reporter, r2, N * sizeof(int));
    assert_len(reporter, r3, 6);

    assert_data(reporter, r1, str, strlen(str));
    assert_data(reporter, r3, "people", 6);

    sk_sp<SkData> tmp(SkData::MakeSubset(r1.get(), strlen(str), 10));
    assert_len(reporter, tmp, 0);
    tmp = SkData::MakeSubset(r1.get(), 0, 0);
    assert_len(reporter, tmp, 0);

    test_cstring(reporter);
    test_files(reporter);

    test_subsets(reporter);
    test_copies(reporter);
}

DEF_TEST(Data_empty, reporter) {
    sk_sp<SkData> array[] = {
        SkData::MakeEmpty(),
        SkData::MakeUninitialized(0),
        SkData::MakeFromMalloc(sk_malloc_throw(0), 0),
        SkData::MakeWithCopy("", 0),
        SkData::MakeWithProc(nullptr, 0, [](const void*, void*){}, nullptr),
        SkData::MakeWithoutCopy(nullptr, 0),
    };
    constexpr int N = std::size(array);

    for (int i = 0; i < N; ++i) {
        REPORTER_ASSERT(reporter, array[i]->size() == 0);
        for (int j = 0; j < N; ++j) {
            REPORTER_ASSERT(reporter, array[i]->equals(array[j].get()));
        }
    }
}
