//* 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 MOCK_DAWN_H
#define MOCK_DAWN_H

#include <gmock/gmock.h>
#include <dawn/dawn.h>

#include <memory>

// An abstract base class representing a proc table so that API calls can be mocked. Most API calls
// are directly represented by a delete virtual method but others need minimal state tracking to be
// useful as mocks.
class ProcTableAsClass {
    public:
        virtual ~ProcTableAsClass();

        void GetProcTableAndDevice(DawnProcTable* table, DawnDevice* device);

        // Creates an object that can be returned by a mocked call as in WillOnce(Return(foo)).
        // It returns an object of the write type that isn't equal to any previously returned object.
        // Otherwise some mock expectation could be triggered by two different objects having the same
        // value.
        {% for type in by_category["object"] %}
            {{as_cType(type.name)}} GetNew{{type.name.CamelCase()}}();
        {% endfor %}

        {% for type in by_category["object"] %}
            {% for method in type.methods if len(method.arguments) < 10 %}
                virtual {{as_cType(method.return_type.name)}} {{as_MethodSuffix(type.name, method.name)}}(
                    {{-as_cType(type.name)}} {{as_varName(type.name)}}
                    {%- for arg in method.arguments -%}
                        , {{as_annotated_cType(arg)}}
                    {%- endfor -%}
                ) = 0;
            {% endfor %}
            virtual void {{as_MethodSuffix(type.name, Name("reference"))}}({{as_cType(type.name)}} self) = 0;
            virtual void {{as_MethodSuffix(type.name, Name("release"))}}({{as_cType(type.name)}} self) = 0;

            // Stores callback and userdata and calls OnBuilderSetErrorCallback
            {% if type.is_builder %}
                void {{as_MethodSuffix(type.name, Name("set error callback"))}}({{as_cType(type.name)}} self, DawnBuilderErrorCallback callback, DawnCallbackUserdata userdata1, DawnCallbackUserdata userdata2);
            {% endif %}
        {% endfor %}

        // Stores callback and userdata and calls the On* methods
        void DeviceSetErrorCallback(DawnDevice self, DawnDeviceErrorCallback callback, DawnCallbackUserdata userdata);
        void BufferMapReadAsync(DawnBuffer self, DawnBufferMapReadCallback callback, DawnCallbackUserdata userdata);
        void BufferMapWriteAsync(DawnBuffer self, DawnBufferMapWriteCallback callback, DawnCallbackUserdata userdata);
        void FenceOnCompletion(DawnFence self,
                               uint64_t value,
                               DawnFenceOnCompletionCallback callback,
                               DawnCallbackUserdata userdata);

        // Special cased mockable methods
        virtual void OnDeviceSetErrorCallback(DawnDevice device, DawnDeviceErrorCallback callback, DawnCallbackUserdata userdata) = 0;
        virtual void OnBuilderSetErrorCallback(DawnBufferBuilder builder, DawnBuilderErrorCallback callback, DawnCallbackUserdata userdata1, DawnCallbackUserdata userdata2) = 0;
        virtual void OnBufferMapReadAsyncCallback(DawnBuffer buffer, DawnBufferMapReadCallback callback, DawnCallbackUserdata userdata) = 0;
        virtual void OnBufferMapWriteAsyncCallback(DawnBuffer buffer, DawnBufferMapWriteCallback callback, DawnCallbackUserdata userdata) = 0;
        virtual void OnFenceOnCompletionCallback(DawnFence fence,
                                                 uint64_t value,
                                                 DawnFenceOnCompletionCallback callback,
                                                 DawnCallbackUserdata userdata) = 0;

        // Calls the stored callbacks
        void CallDeviceErrorCallback(DawnDevice device, const char* message);
        void CallBuilderErrorCallback(void* builder , DawnBuilderErrorStatus status, const char* message);
        void CallMapReadCallback(DawnBuffer buffer, DawnBufferMapAsyncStatus status, const void* data, uint32_t dataLength);
        void CallMapWriteCallback(DawnBuffer buffer, DawnBufferMapAsyncStatus status, void* data, uint32_t dataLength);
        void CallFenceOnCompletionCallback(DawnFence fence, DawnFenceCompletionStatus status);

        struct Object {
            ProcTableAsClass* procs = nullptr;
            DawnDeviceErrorCallback deviceErrorCallback = nullptr;
            DawnBuilderErrorCallback builderErrorCallback = nullptr;
            DawnBufferMapReadCallback mapReadCallback = nullptr;
            DawnBufferMapWriteCallback mapWriteCallback = nullptr;
            DawnFenceOnCompletionCallback fenceOnCompletionCallback = nullptr;
            DawnCallbackUserdata userdata1 = 0;
            DawnCallbackUserdata userdata2 = 0;
        };

    private:
        // Remembers the values returned by GetNew* so they can be freed.
        std::vector<std::unique_ptr<Object>> mObjects;
};

class MockProcTable : public ProcTableAsClass {
    public:
        MockProcTable();

        {% for type in by_category["object"] %}
            {% for method in type.methods if len(method.arguments) < 10 %}
                MOCK_METHOD{{len(method.arguments) + 1}}(
                    {{-as_MethodSuffix(type.name, method.name)}},
                    {{as_cType(method.return_type.name)}}(
                        {{-as_cType(type.name)}} {{as_varName(type.name)}}
                        {%- for arg in method.arguments -%}
                            , {{as_annotated_cType(arg)}}
                        {%- endfor -%}
                    ));
            {% endfor %}

            MOCK_METHOD1({{as_MethodSuffix(type.name, Name("reference"))}}, void({{as_cType(type.name)}} self));
            MOCK_METHOD1({{as_MethodSuffix(type.name, Name("release"))}}, void({{as_cType(type.name)}} self));
        {% endfor %}

        MOCK_METHOD3(OnDeviceSetErrorCallback, void(DawnDevice device, DawnDeviceErrorCallback callback, DawnCallbackUserdata userdata));
        MOCK_METHOD4(OnBuilderSetErrorCallback, void(DawnBufferBuilder builder, DawnBuilderErrorCallback callback, DawnCallbackUserdata userdata1, DawnCallbackUserdata userdata2));
        MOCK_METHOD3(OnBufferMapReadAsyncCallback, void(DawnBuffer buffer, DawnBufferMapReadCallback callback, DawnCallbackUserdata userdata));
        MOCK_METHOD3(OnBufferMapWriteAsyncCallback, void(DawnBuffer buffer, DawnBufferMapWriteCallback callback, DawnCallbackUserdata userdata));
        MOCK_METHOD4(OnFenceOnCompletionCallback,
                     void(DawnFence fence,
                          uint64_t value,
                          DawnFenceOnCompletionCallback callback,
                          DawnCallbackUserdata userdata));
};

#endif // MOCK_DAWN_H
