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

#ifndef SRC_DAWN_TESTS_UNITTESTS_WIRE_WIRETEST_H_
#define SRC_DAWN_TESTS_UNITTESTS_WIRE_WIRETEST_H_

#include <memory>

#include "dawn/mock_webgpu.h"
#include "gtest/gtest.h"

// 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:
    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;
};

#endif  // SRC_DAWN_TESTS_UNITTESTS_WIRE_WIRETEST_H_
