// Copyright 2019 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 "dawn/mock_webgpu.h"
#include "gtest/gtest.h"

#include <memory>

// Definition of a "Lambda predicate matcher" for GMock to allow checking deep structures
// are passed correctly by the wire.

// Helper templates to extract the argument type of a lambda.
template <typename T>
struct MatcherMethodArgument;

template <typename Lambda, typename Arg>
struct MatcherMethodArgument<bool (Lambda::*)(Arg) const> {
    using Type = Arg;
};

template <typename Lambda>
using MatcherLambdaArgument = typename MatcherMethodArgument<decltype(&Lambda::operator())>::Type;

// The matcher itself, unfortunately it isn't able to return detailed information like other
// matchers do.
template <typename Lambda, typename Arg>
class LambdaMatcherImpl : public testing::MatcherInterface<Arg> {
  public:
    explicit LambdaMatcherImpl(Lambda lambda) : mLambda(lambda) {
    }

    void DescribeTo(std::ostream* os) const override {
        *os << "with a custom matcher";
    }

    bool MatchAndExplain(Arg value, testing::MatchResultListener* listener) const override {
        if (!mLambda(value)) {
            *listener << "which doesn't satisfy the custom predicate";
            return false;
        }
        return true;
    }

  private:
    Lambda mLambda;
};

// Use the MatchesLambda as follows:
//
//   EXPECT_CALL(foo, Bar(MatchesLambda([](ArgType arg) -> bool {
//       return CheckPredicateOnArg(arg);
//   })));
template <typename Lambda>
inline testing::Matcher<MatcherLambdaArgument<Lambda>> MatchesLambda(Lambda lambda) {
    return MakeMatcher(new LambdaMatcherImpl<Lambda, MatcherLambdaArgument<Lambda>>(lambda));
}

class StringMessageMatcher : public testing::MatcherInterface<const char*> {
  public:
    explicit StringMessageMatcher() {
    }

    bool MatchAndExplain(const char* message,
                         testing::MatchResultListener* listener) const override {
        if (message == nullptr) {
            *listener << "missing error message";
            return false;
        }
        if (std::strlen(message) <= 1) {
            *listener << "message is truncated";
            return false;
        }
        return true;
    }

    void DescribeTo(std::ostream* os) const override {
        *os << "valid error message";
    }

    void DescribeNegationTo(std::ostream* os) const override {
        *os << "invalid error message";
    }
};

inline testing::Matcher<const char*> ValidStringMessage() {
    return MakeMatcher(new StringMessageMatcher());
}

namespace dawn_wire {
    class WireClient;
    class WireServer;
    namespace client {
        class MemoryTransferService;
    }  // namespace client
    namespace server {
        class MemoryTransferService;
    }  // namespace server
}  // namespace dawn_wire

namespace utils {
    class TerribleCommandBuffer;
}

class WireTest : public testing::Test {
  protected:
    WireTest();
    ~WireTest() override;

    void SetUp() override;
    void TearDown() override;

    void FlushClient(bool success = true);
    void FlushServer(bool success = true);

    void DefaultApiDeviceWasReleased();

    testing::StrictMock<MockProcTable> api;
    WGPUDevice apiDevice;
    WGPUQueue apiQueue;
    WGPUDevice device;
    WGPUQueue queue;

    dawn_wire::WireServer* GetWireServer();
    dawn_wire::WireClient* GetWireClient();

    void DeleteServer();
    void DeleteClient();

  private:
    void SetupIgnoredCallExpectations();

    virtual dawn_wire::client::MemoryTransferService* GetClientMemoryTransferService();
    virtual dawn_wire::server::MemoryTransferService* GetServerMemoryTransferService();

    std::unique_ptr<dawn_wire::WireServer> mWireServer;
    std::unique_ptr<dawn_wire::WireClient> mWireClient;
    std::unique_ptr<utils::TerribleCommandBuffer> mS2cBuf;
    std::unique_ptr<utils::TerribleCommandBuffer> mC2sBuf;
};
