// Copyright 2022 The Dawn Authors
//
// 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 <gmock/gmock.h>
#include <gtest/gtest.h>

#include <cstring>
#include <iomanip>
#include <string>

#include "dawn/native/CacheKey.h"

namespace dawn::native {

    // Testing classes with mock serializing implemented for testing.
    class A {
      public:
        MOCK_METHOD(void, SerializeMock, (CacheKey*, const A&), (const));
    };
    template <>
    void CacheKeySerializer<A>::Serialize(CacheKey* key, const A& t) {
        t.SerializeMock(key, t);
    }

    // Custom printer for CacheKey for clearer debug testing messages.
    void PrintTo(const CacheKey& key, std::ostream* stream) {
        *stream << std::hex;
        for (const int b : key) {
            *stream << std::setfill('0') << std::setw(2) << b << " ";
        }
        *stream << std::dec;
    }

    namespace {

        using ::testing::InSequence;
        using ::testing::NotNull;
        using ::testing::PrintToString;
        using ::testing::Ref;

        // Matcher to compare CacheKeys for easier testing.
        MATCHER_P(CacheKeyEq, key, PrintToString(key)) {
            return arg.size() == key.size() && memcmp(arg.data(), key.data(), key.size()) == 0;
        }

        TEST(CacheKeyTests, RecordSingleMember) {
            CacheKey key;

            A a;
            EXPECT_CALL(a, SerializeMock(NotNull(), Ref(a))).Times(1);
            EXPECT_THAT(key.Record(a), CacheKeyEq(CacheKey()));
        }

        TEST(CacheKeyTests, RecordManyMembers) {
            constexpr size_t kNumMembers = 100;

            CacheKey key;
            for (size_t i = 0; i < kNumMembers; ++i) {
                A a;
                EXPECT_CALL(a, SerializeMock(NotNull(), Ref(a))).Times(1);
                key.Record(a);
            }
            EXPECT_THAT(key, CacheKeyEq(CacheKey()));
        }

        TEST(CacheKeyTests, RecordIterable) {
            constexpr size_t kIterableSize = 100;

            // Expecting the size of the container.
            CacheKey expected;
            expected.Record(kIterableSize);

            std::vector<A> iterable(kIterableSize);
            {
                InSequence seq;
                for (const auto& a : iterable) {
                    EXPECT_CALL(a, SerializeMock(NotNull(), Ref(a))).Times(1);
                }
                for (const auto& a : iterable) {
                    EXPECT_CALL(a, SerializeMock(NotNull(), Ref(a))).Times(1);
                }
            }

            EXPECT_THAT(CacheKey().RecordIterable(iterable), CacheKeyEq(expected));
            EXPECT_THAT(CacheKey().RecordIterable(iterable.data(), kIterableSize),
                        CacheKeyEq(expected));
        }

        TEST(CacheKeyTests, RecordNested) {
            CacheKey expected;
            CacheKey actual;
            {
                // Recording a single member.
                A a;
                EXPECT_CALL(a, SerializeMock(NotNull(), Ref(a))).Times(1);
                actual.Record(CacheKey().Record(a));
            }
            {
                // Recording multiple members.
                constexpr size_t kNumMembers = 2;
                CacheKey sub;
                for (size_t i = 0; i < kNumMembers; ++i) {
                    A a;
                    EXPECT_CALL(a, SerializeMock(NotNull(), Ref(a))).Times(1);
                    sub.Record(a);
                }
                actual.Record(sub);
            }
            {
                // Record an iterable.
                constexpr size_t kIterableSize = 2;
                expected.Record(kIterableSize);
                std::vector<A> iterable(kIterableSize);
                {
                    InSequence seq;
                    for (const auto& a : iterable) {
                        EXPECT_CALL(a, SerializeMock(NotNull(), Ref(a))).Times(1);
                    }
                }
                actual.Record(CacheKey().RecordIterable(iterable));
            }
            EXPECT_THAT(actual, CacheKeyEq(expected));
        }

        TEST(CacheKeySerializerTests, IntegralTypes) {
            // Only testing explicitly sized types for simplicity, and using 0s for larger types to
            // avoid dealing with endianess.
            EXPECT_THAT(CacheKey().Record('c'), CacheKeyEq(CacheKey({'c'})));
            EXPECT_THAT(CacheKey().Record(uint8_t(255)), CacheKeyEq(CacheKey({255})));
            EXPECT_THAT(CacheKey().Record(uint16_t(0)), CacheKeyEq(CacheKey({0, 0})));
            EXPECT_THAT(CacheKey().Record(uint32_t(0)), CacheKeyEq(CacheKey({0, 0, 0, 0})));
        }

        TEST(CacheKeySerializerTests, FloatingTypes) {
            // Using 0s to avoid dealing with implementation specific float details.
            EXPECT_THAT(CacheKey().Record(float(0)), CacheKeyEq(CacheKey(sizeof(float), 0)));
            EXPECT_THAT(CacheKey().Record(double(0)), CacheKeyEq(CacheKey(sizeof(double), 0)));
        }

        TEST(CacheKeySerializerTests, LiteralStrings) {
            // Using a std::string here to help with creating the expected result.
            std::string str = "string";

            CacheKey expected;
            expected.Record(size_t(7));
            expected.insert(expected.end(), str.begin(), str.end());
            expected.push_back('\0');

            EXPECT_THAT(CacheKey().Record("string"), CacheKeyEq(expected));
        }

        TEST(CacheKeySerializerTests, StdStrings) {
            std::string str = "string";

            CacheKey expected;
            expected.Record((size_t)6);
            expected.insert(expected.end(), str.begin(), str.end());

            EXPECT_THAT(CacheKey().Record(str), CacheKeyEq(expected));
        }

        TEST(CacheKeySerializerTests, CacheKeys) {
            CacheKey data = {'d', 'a', 't', 'a'};

            CacheKey expected;
            expected.insert(expected.end(), data.begin(), data.end());

            EXPECT_THAT(CacheKey().Record(data), CacheKeyEq(expected));
        }

    }  // namespace

}  // namespace dawn::native
