/*
 * Copyright 2020 The Android Open Source Project
 *
 * 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.
 */

#define METADATA_TESTING

#include <audio_utils/Metadata.h>
#include <gtest/gtest.h>
#include <stdio.h>

#include <error.h>
#include <iostream>

using namespace android::audio_utils::metadata;

// Preferred: Key in header - a constexpr which is created by the compiler.
inline constexpr CKey<std::string> ITS_NAME_IS("its_name_is");

// Not preferred: Key which is created at run-time.
inline const Key<std::string> MY_NAME_IS("my_name_is");

// The Metadata table
inline constexpr CKey<Data> TABLE("table");

#ifdef METADATA_TESTING

// Validate recursive typing on "Datum".
inline constexpr CKey<std::vector<Datum>> VECTOR("vector");
inline constexpr CKey<std::pair<Datum, Datum>> PAIR("pair");

// Validate that we move instead of copy.
inline constexpr CKey<MoveCount> MOVE_COUNT("MoveCount");

// Validate recursive container support.
inline constexpr CKey<std::vector<std::vector<std::pair<std::string, short>>>> FUNKY("funky");

// Validate structured binding parceling.
inline constexpr CKey<Arbitrary> ARBITRARY("arbitrary");
#endif

std::string toString(const ByteString &bs) {
    std::stringstream ss;
    ss << "{\n" << std::hex;
    if (bs.size() > 0) {
        for (size_t i = 0; ; ++i) {
            if ((i & 7) == 0) {
                ss << "  ";
            }
            ss << "0x" <<  std::setfill('0') << std::setw(2) << (unsigned)bs[i];
            if (i == bs.size() - 1) {
                break;
            } else if ((i & 7) == 7) {
                ss << ",\n";
            } else {
                ss << ", ";
            }
        }
    }
    ss << "\n}\n";
    return ss.str();
}

TEST(metadata_tests, basic_datum) {
    Datum d;
    d = "abc";
    //ASSERT_EQ("abc", std::any_cast<const char *>(d));
    ASSERT_EQ("abc", std::any_cast<std::string>(d));
    //d = std::vector<int>();

    Datum lore((int32_t) 10);
    d = lore;
    ASSERT_EQ(10, std::any_cast<int32_t>(d));

    // TODO: should we enable Datum to copy from std::any if the types
    // are correct?  The problem is how to signal failure.
    std::any arg = (int)1;
    // Datum invalid = arg; // this doesn't work.

    struct dummy {
        int value = 0;
    };

    // check apply with a void function
    {
        // try to apply with an invalid argument
        int value = 0;

        arg = dummy{}; // not an expected type, apply will fail with false.
        std::any result;

        ASSERT_FALSE(primitive_metadata_types::apply([&](auto *t __attribute__((unused))) {
                value++;
            }, &arg, &result));

        ASSERT_EQ(0, value);              // never invoked.
        ASSERT_FALSE(result.has_value()); // no value returned.

        // try to apply with a valid argument.
        arg = (int)1;

        ASSERT_TRUE(primitive_metadata_types::apply([&](auto *t __attribute__((unused))) {
                value++;
            }, &arg, &result));

        ASSERT_EQ(1, value);              // invoked once.
        ASSERT_FALSE(result.has_value()); // no value returned (function returns void).
    }

    // check apply with a function that returns 2.
    {
        int value = 0;
        arg = (int)1;
        std::any result;

        ASSERT_TRUE(primitive_metadata_types::apply([&](auto *t __attribute__((unused))) {
                value++;
                return (int32_t)2;
            }, &arg, &result));

        ASSERT_EQ(1, value);                          // invoked once.
        ASSERT_EQ(2, std::any_cast<int32_t>(result)); // 2 returned
    }

#ifdef METADATA_TESTING
    // Checks the number of moves versus copies as the datum flows through Data.
    // the counters should increment each time a MoveCount gets copied or
    // moved.

    //  Datum mc = MoveCount();

    Datum mc{MoveCount()};
    ASSERT_TRUE(1 >= std::any_cast<MoveCount>(mc).mMoveCount); // no more than 1 move.
    ASSERT_EQ(0, std::any_cast<MoveCount>(&mc)->mCopyCount);   // no copies
    ASSERT_EQ(1, std::any_cast<MoveCount>(mc).mCopyCount);     // Note: any_cast on value copies.


    // serialize
    ByteString bs;
    ASSERT_TRUE(copyToByteString(mc, bs));
    // deserialize
    size_t idx = 0;
    Datum parceled;
    ASSERT_TRUE(copyFromByteString(&parceled, bs, idx, nullptr /* unknowns */));

    // everything OK with the received data?
    ASSERT_EQ(bs.size(), idx);          // no data left over.
    ASSERT_TRUE(parceled.has_value());  // we have a value.

    // confirm no copies.
    ASSERT_TRUE(2 >= std::any_cast<MoveCount>(&parceled)->mMoveCount); // no more than 2 moves.
    ASSERT_EQ(0, std::any_cast<MoveCount>(&parceled)->mCopyCount);
#endif
}

TEST(metadata_tests, basic_data) {
    Data d;
    d.emplace("int32", (int32_t)1);
    d.emplace("int64", (int64_t)2);
    d.emplace("float", (float)3.1f);
    d.emplace("double", (double)4.11);
    d.emplace("string", "hello");
    d["string2"] = "world";

    // Put with typed keys
    d.put(MY_NAME_IS, "neo");
    d[ITS_NAME_IS] = "spot";

    ASSERT_EQ(1, std::any_cast<int32_t>(d["int32"]));
    ASSERT_EQ(2, std::any_cast<int64_t>(d["int64"]));
    ASSERT_EQ(3.1f, std::any_cast<float>(d["float"]));
    ASSERT_EQ(4.11, std::any_cast<double>(d["double"]));
    ASSERT_EQ("hello", std::any_cast<std::string>(d["string"]));
    ASSERT_EQ("world", std::any_cast<std::string>(d["string2"]));

    // Get with typed keys
    ASSERT_EQ("neo", *d.get_ptr(MY_NAME_IS));
    ASSERT_EQ("spot", *d.get_ptr(ITS_NAME_IS));

    ASSERT_EQ("neo", d[MY_NAME_IS]);
    ASSERT_EQ("spot", d[ITS_NAME_IS]);

    ByteString bs = byteStringFromData(d);
    Data data = dataFromByteString(bs);
    ASSERT_EQ((size_t)8, data.size());

    ASSERT_EQ(1, std::any_cast<int32_t>(data["int32"]));
    ASSERT_EQ(2, std::any_cast<int64_t>(data["int64"]));
    ASSERT_EQ(3.1f, std::any_cast<float>(data["float"]));
    ASSERT_EQ(4.11, std::any_cast<double>(data["double"]));
    ASSERT_EQ("hello", std::any_cast<std::string>(data["string"]));
    ASSERT_EQ("neo", *data.get_ptr(MY_NAME_IS));
    ASSERT_EQ("spot", *data.get_ptr(ITS_NAME_IS));

    data[MY_NAME_IS] = "one";
    ASSERT_EQ("one", data[MY_NAME_IS]);

    // Keys are typed, so this fails to compile.
    // data->put(MY_NAME_IS, 10);

#ifdef METADATA_TESTING
    // Checks the number of moves versus copies as the Datum goes to
    // Data and then parceled and unparceled.
    // The counters should increment each time a MoveCount gets copied or
    // moved.
    {
        Data d2;
        d2[MOVE_COUNT] = MoveCount(); // should be moved.

        ASSERT_TRUE(1 >= d2[MOVE_COUNT].mMoveCount); // no more than one move.
        ASSERT_EQ(0, d2[MOVE_COUNT].mCopyCount);     // no copies

        ByteString bs = byteStringFromData(d2);
        Data d3 = dataFromByteString(bs);

        ASSERT_EQ(0, d3[MOVE_COUNT].mCopyCount);     // no copies
        ASSERT_TRUE(2 >= d3[MOVE_COUNT].mMoveCount); // no more than 2 moves after parceling
    }
#endif
}

TEST(metadata_tests, complex_data) {
    Data small;
    Data big;

    small[MY_NAME_IS] = "abc";
#ifdef METADATA_TESTING
    small[MOVE_COUNT] = MoveCount{};
#endif
    big[TABLE] = small;  // ONE COPY HERE of the MoveCount (embedded in small).

#ifdef METADATA_TESTING
    big[VECTOR] = std::vector<Datum>{small, small};
    big[PAIR] = std::make_pair<Datum, Datum>(small, small);
    ASSERT_EQ(1, big[TABLE][MOVE_COUNT].mCopyCount); // one copy done for small.

    big[FUNKY] = std::vector<std::vector<std::pair<std::string, short>>>{
        {{"a", 1}, {"b", 2}},
        {{"c", 3}, {"d", 4}},
    };

    // struct Arbitrary { int i0; std::vector<int> v1; std::pair<int, int> p2; };
    big[ARBITRARY] = Arbitrary{0, {1, 2, 3}, {4, 5}};
#endif

    // Try round-trip conversion to a ByteString.
    ByteString bs = byteStringFromData(big);
    Data data = dataFromByteString(bs);
#ifdef METADATA_TESTING
    ASSERT_EQ((size_t)5, data.size());
#else
    ASSERT_EQ((size_t)1, data.size());
#endif

    // Nested tables make sense.
    ASSERT_EQ("abc", data[TABLE][MY_NAME_IS]);

#ifdef METADATA_TESTING
    // TODO: Maybe we don't need the vector or the pair.
    ASSERT_EQ("abc", std::any_cast<Data>(data[VECTOR][1])[MY_NAME_IS]);
    ASSERT_EQ("abc", std::any_cast<Data>(data[PAIR].first)[MY_NAME_IS]);
    ASSERT_EQ(1, data[TABLE][MOVE_COUNT].mCopyCount); // no additional copies.

    auto funky = data[FUNKY];
    ASSERT_EQ("a", funky[0][0].first);
    ASSERT_EQ(4, funky[1][1].second);

    auto arbitrary = data[ARBITRARY];
    ASSERT_EQ(0, arbitrary.i0);
    ASSERT_EQ(2, arbitrary.v1[1]);
    ASSERT_EQ(4, arbitrary.p2.first);
#endif
}

// DO NOT CHANGE THIS after R, but add a new test.
TEST(metadata_tests, compatibility_R) {
    Data d;
    d.emplace("i32", (int32_t)1);
    d.emplace("i64", (int64_t)2);
    d.emplace("float", (float)3.1f);
    d.emplace("double", (double)4.11);
    Data s;
    s.emplace("string", "hello");
    d.emplace("data", s);

    ByteString bs = byteStringFromData(d);
    printf("%s\n", toString(bs).c_str());

    // Since we use a map instead of a hashmap
    // layout order of elements is precisely defined.
    ByteString reference = {
        0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
        0x64, 0x61, 0x74, 0x61, 0x06, 0x00, 0x00, 0x00,
        0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
        0x06, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x69,
        0x6e, 0x67, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00,
        0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x68, 0x65,
        0x6c, 0x6c, 0x6f, 0x06, 0x00, 0x00, 0x00, 0x64,
        0x6f, 0x75, 0x62, 0x6c, 0x65, 0x04, 0x00, 0x00,
        0x00, 0x08, 0x00, 0x00, 0x00, 0x71, 0x3d, 0x0a,
        0xd7, 0xa3, 0x70, 0x10, 0x40, 0x05, 0x00, 0x00,
        0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x03, 0x00,
        0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66, 0x66,
        0x46, 0x40, 0x03, 0x00, 0x00, 0x00, 0x69, 0x33,
        0x32, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
        0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
        0x00, 0x69, 0x36, 0x34, 0x02, 0x00, 0x00, 0x00,
        0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00
    };
    ASSERT_EQ(reference, bs);

    Data decoded = dataFromByteString(bs);

    // TODO: data equality.
    // ASSERT_EQ(decoded, d);

    ASSERT_EQ(1, std::any_cast<int32_t>(decoded["i32"]));
    ASSERT_EQ(2, std::any_cast<int64_t>(decoded["i64"]));
    ASSERT_EQ(3.1f, std::any_cast<float>(decoded["float"]));
    ASSERT_EQ(4.11, std::any_cast<double>(decoded["double"]));
    Data decoded_s = std::any_cast<Data>(decoded["data"]);

    ASSERT_EQ("hello", std::any_cast<std::string>(s["string"]));

    {
        ByteString unknownData = reference;
        unknownData[12] = 0xff;
        Data decoded2 = dataFromByteString(unknownData);
        ASSERT_EQ((size_t)0, decoded2.size());

        ByteStringUnknowns unknowns;
        Data decoded3 = dataFromByteString(unknownData, &unknowns);
        ASSERT_EQ((size_t)4, decoded3.size());
        ASSERT_EQ((size_t)1, unknowns.size());
        ASSERT_EQ((unsigned)0xff, unknowns[0]);
    }

    {
        ByteString unknownDouble = reference;
        ASSERT_EQ(0x4, unknownDouble[0x3d]);
        unknownDouble[0x3d] = 0xfe;
        Data decoded2 = dataFromByteString(unknownDouble);
        ASSERT_EQ((size_t)0, decoded2.size());

        ByteStringUnknowns unknowns;
        Data decoded3 = dataFromByteString(unknownDouble, &unknowns);
        ASSERT_EQ((size_t)4, decoded3.size());
        ASSERT_EQ((size_t)1, unknowns.size());
        ASSERT_EQ((unsigned)0xfe, unknowns[0]);
    }
};

TEST(metadata_tests, bytestring_examples) {
    ByteString bs;

    copyToByteString((int32_t)123, bs);
    printf("123 -> %s\n", toString(bs).c_str());
    const ByteString ref1{ 0x7b, 0x00, 0x00, 0x00 };
    ASSERT_EQ(ref1, bs);

    bs.clear();
    // for copyToByteString use std::string instead of char array.
    copyToByteString(std::string("hi"), bs);
    printf("\"hi\" -> %s\n", toString(bs).c_str());
    const ByteString ref2{ 0x02, 0x00, 0x00, 0x00, 0x68, 0x69 };
    ASSERT_EQ(ref2, bs);

    bs.clear();
    Data d;
    d.emplace("hello", "world");
    d.emplace("value", (int32_t)1000);
    copyToByteString(d, bs);
    printf("{{\"hello\", \"world\"}, {\"value\", 1000}} -> %s\n", toString(bs).c_str());
    const ByteString ref3{
        0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
        0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x05, 0x00, 0x00,
        0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
        0x00, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x05, 0x00,
        0x00, 0x00, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x01,
        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe8,
        0x03, 0x00, 0x00};
    ASSERT_EQ(ref3, bs);
};

// Test C API from C++
TEST(metadata_tests, c) {
    audio_metadata_t *metadata = audio_metadata_create();
    Data d;
    d.emplace("i32", (int32_t)1);
    d.emplace("i64", (int64_t)2);
    d.emplace("float", (float)3.1f);
    d.emplace("double", (double)4.11);
    Data s;
    s.emplace("string", "hello");
    d.emplace("data", s);

    audio_metadata_put(metadata, "i32", (int32_t)1);
    audio_metadata_put(metadata, "i64", (int64_t)2);
    audio_metadata_put(metadata, "float", (float)3.1f);
    audio_metadata_put(metadata, "double", (double)4.11);
    audio_metadata_t *data = audio_metadata_create();
    audio_metadata_put(data, "string", "hello");
    audio_metadata_put(metadata, "data", data);
#if 0   // candidate function not viable: no known conversion
    {
        static const struct complex {
            float re;
            float im;
        } prime = { -5.0, -4.0 };
        audio_metadata_put(metadata, "complex", prime);
    }
#endif
    audio_metadata_destroy(data);

    int32_t i32Val;
    int64_t i64Val;
    float floatVal;
    double doubleVal;
    char *strVal = nullptr;
    audio_metadata_t *dataVal = nullptr;
    ASSERT_EQ(0, audio_metadata_get(metadata, "i32", &i32Val));
    ASSERT_EQ(1, i32Val);
    ASSERT_EQ(0, audio_metadata_get(metadata, "i64", &i64Val));
    ASSERT_EQ(2, i64Val);
    ASSERT_EQ(0, audio_metadata_get(metadata, "float", &floatVal));
    ASSERT_EQ(3.1f, floatVal);
    ASSERT_EQ(0, audio_metadata_get(metadata, "double", &doubleVal));
    ASSERT_EQ(4.11, doubleVal);
    ASSERT_EQ(0, audio_metadata_get(metadata, "data", &dataVal));
    ASSERT_NE(dataVal, nullptr);
    ASSERT_EQ(0, audio_metadata_get(dataVal, "string", &strVal));
    ASSERT_EQ(0, strcmp("hello", strVal));
    free(strVal);
    audio_metadata_destroy(dataVal);
    dataVal = nullptr;
    ASSERT_EQ(-ENOENT, audio_metadata_get(metadata, "non_exist_key", &i32Val));
    audio_metadata_t *nullMetadata = nullptr;
    ASSERT_EQ(-EINVAL, audio_metadata_get(nullMetadata, "i32", &i32Val));
    char *nullKey = nullptr;
    ASSERT_EQ(-EINVAL, audio_metadata_get(metadata, nullKey, &i32Val));
    int *nullI32Val = nullptr;
    ASSERT_EQ(-EINVAL, audio_metadata_get(metadata, "i32", nullI32Val));

    uint8_t *bs = nullptr;
    ssize_t length = byte_string_from_audio_metadata(metadata, &bs);
    ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
    ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
    ASSERT_EQ((size_t)length, dataByteStringLen(bs));
    ASSERT_EQ(byteStringFromData(d).size(), ByteString(bs, bs + length).size());
    audio_metadata_t *metadataFromBs = audio_metadata_from_byte_string(bs, length);
    free(bs);
    bs = nullptr;
    length = byte_string_from_audio_metadata(metadataFromBs, &bs);
    ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
    ASSERT_EQ(byteStringFromData(d), ByteString(bs, bs + length));
    ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
    ASSERT_EQ((size_t)length, dataByteStringLen(bs));
    free(bs);
    bs = nullptr;
    audio_metadata_destroy(metadataFromBs);
    ASSERT_EQ(-EINVAL, byte_string_from_audio_metadata(nullMetadata, &bs));
    uint8_t **nullBs = nullptr;
    ASSERT_EQ(-EINVAL, byte_string_from_audio_metadata(metadata, nullBs));

    ASSERT_EQ(1, audio_metadata_erase(metadata, "data"));
    // initialize to a known invalid pointer
    dataVal = reinterpret_cast<audio_metadata_t *>(reinterpret_cast<intptr_t>(nullptr) + 1);
    ASSERT_EQ(-ENOENT, audio_metadata_get(metadata, "data", &dataVal));
    // confirm that a failed get will assign nullptr; be sure to
    // update test if API behavior is changed to not assign nullptr on error
    ASSERT_EQ(nullptr, dataVal);
    ASSERT_EQ(0, audio_metadata_erase(metadata, "data"));
    ASSERT_EQ(-EINVAL, audio_metadata_erase(nullMetadata, "key"));
    ASSERT_EQ(-EINVAL, audio_metadata_erase(metadata, nullKey));

    audio_metadata_destroy(metadata);
};

TEST(metadata_tests, empty_data_c) {
    std::unique_ptr<audio_metadata_t, decltype(&audio_metadata_destroy)>
        metadata{audio_metadata_create(), audio_metadata_destroy};  // empty metadata container.
    uint8_t *bs = nullptr;
    ssize_t length = byte_string_from_audio_metadata(metadata.get(), &bs);
    ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
    std::unique_ptr<uint8_t, decltype(&free)> bs_scoped_deleter{bs, free};
    ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
    ASSERT_EQ((size_t)length, dataByteStringLen(bs));

    Data d;  // empty metadata container.
    ASSERT_EQ(byteStringFromData(d).size(), ByteString(bs, bs + length).size());
    std::unique_ptr<audio_metadata_t, decltype(&audio_metadata_destroy)>
            metadataFromBs{audio_metadata_from_byte_string(bs, length), audio_metadata_destroy};
    length = byte_string_from_audio_metadata(metadataFromBs.get(), &bs);
    ASSERT_GT(length, 0); // if gt 0, the bs has been updated to a new value.
    bs_scoped_deleter.reset(bs);
    ASSERT_EQ(byteStringFromData(d), ByteString(bs, bs + length));
    ASSERT_EQ((size_t)length, audio_metadata_byte_string_len(bs));
    ASSERT_EQ((size_t)length, dataByteStringLen(bs));
};
