// Copyright 2017 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.

#ifndef TESTS_UNITTESTS_VALIDATIONTEST_H_
#define TESTS_UNITTESTS_VALIDATIONTEST_H_

#include "gtest/gtest.h"
#include "dawn/dawncpp.h"
#include "dawn/dawncpp_traits.h"

namespace dawn_native {
    class Instance;
};

#define ASSERT_DEVICE_ERROR(statement) \
    StartExpectDeviceError(); \
    statement; \
    ASSERT_TRUE(EndExpectDeviceError());

class ValidationTest : public testing::Test {
    public:
        ValidationTest();
        ~ValidationTest();

        void TearDown() override;

        // Use these methods to add expectations on the validation of a builder. The expectations are
        // checked on test teardown. Adding an expectation is done like the following:
        //
        //     dawn::Foo foo = AssertWillBe[Success|Error](device.CreateFooBuilder(), "my foo")
        //         .SetBar(1)
        //         .GetResult();
        //
        // The string argument is optional but will be printed when an expectations is missed, this
        // will help debug tests where multiple expectations are added.
        template<typename Builder>
        Builder AssertWillBeSuccess(Builder builder, std::string debugName = "");
        template<typename Builder>
        Builder AssertWillBeError(Builder builder, std::string debugName = "");

        void StartExpectDeviceError();
        bool EndExpectDeviceError();
        std::string GetLastDeviceErrorMessage() const;

        dawn::RenderPassDescriptor CreateSimpleRenderPass();

        // Helper functions to create objects to test validation.

        struct DummyRenderPass {
            dawn::RenderPassDescriptor renderPass;
            dawn::Texture attachment;
            dawn::TextureFormat attachmentFormat;
            uint32_t width;
            uint32_t height;
        };
        DummyRenderPass CreateDummyRenderPass();

    protected:
        dawn::Device device;

    private:
        std::unique_ptr<dawn_native::Instance> mInstance;

        static void OnDeviceError(const char* message, dawnCallbackUserdata userdata);
        std::string mDeviceErrorMessage;
        bool mExpectError = false;
        bool mError = false;

        struct BuilderStatusExpectations {
            bool expectSuccess;
            std::string debugName;

            bool gotStatus = false;
            std::string statusMessage;
            dawnBuilderErrorStatus status;
        };
        std::vector<BuilderStatusExpectations> mExpectations;

        template<typename Builder>
        Builder AddExpectation(Builder& builder, std::string debugName, bool expectSuccess);

        static void OnBuilderErrorStatus(dawnBuilderErrorStatus status, const char* message, dawn::CallbackUserdata userdata1, dawn::CallbackUserdata userdata2);
};

// Template implementation details

template<typename Builder>
Builder ValidationTest::AssertWillBeSuccess(Builder builder, std::string debugName) {
    return AddExpectation(builder, debugName, true);
}

template<typename Builder>
Builder ValidationTest::AssertWillBeError(Builder builder, std::string debugName) {
    return AddExpectation(builder, debugName, false);
}

template<typename Builder>
Builder ValidationTest::AddExpectation(Builder& builder, std::string debugName, bool expectSuccess) {
    uint64_t userdata1 = reinterpret_cast<uintptr_t>(this);
    uint64_t userdata2 = mExpectations.size();
    builder.SetErrorCallback(OnBuilderErrorStatus, userdata1, userdata2);

    mExpectations.emplace_back();
    auto& expectation = mExpectations.back();
    expectation.expectSuccess = expectSuccess;
    expectation.debugName = debugName;

    return std::move(builder);
}

#endif // TESTS_UNITTESTS_VALIDATIONTEST_H_
