// Copyright 2016 Google Inc.
//
// 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.
//
// Author: cheesy@google.com (Steve Hill)

#ifndef PAGESPEED_CONTROLLER_CONTROLLER_GRPC_MOCKS_H_
#define PAGESPEED_CONTROLLER_CONTROLLER_GRPC_MOCKS_H_

#include "pagespeed/controller/controller.grpc.pb.h"
#include "pagespeed/controller/controller.pb.h"
#include "pagespeed/kernel/base/function.h"
#include "pagespeed/kernel/base/gmock.h"
#include "pagespeed/kernel/base/proto_util.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/thread/sequence.h"
#include "pagespeed/kernel/thread/worker_test_base.h"
#include "pagespeed/kernel/util/grpc.h"

// Various mocks and related classes that are useful for testing client-side
// CentralController gRPC stuff.

using testing::_;
using testing::Eq;
using testing::Invoke;
using testing::WithArgs;
using testing::Return;
using testing::SetArgPointee;

namespace net_instaweb {

// Function wrapper that Notify()s a SyncPoint after running another contained
// Function.

class NotifyFunction : public Function {
 public:
  NotifyFunction(Function* func, WorkerTestBase::SyncPoint* sync)
      : func_(func), sync_(sync) {}

  void Run() override {
    func_->CallRun();
    sync_->Notify();
  }

  void Cancel() override {
    func_->CallCancel();
    sync_->Notify();
  }

 private:
  Function* func_;
  WorkerTestBase::SyncPoint* sync_;
};

// Mock for grpc::ClientAsyncReaderWriterInterface.
// All callbacks are invoked asynchronously through a Sequence to mimic the
// equivalent gRPC behaviour which uses a gRPC CompletionQueue.

template <typename RequestT, typename ResponseT>
class MockReaderWriterT
    : public ::grpc::ClientAsyncReaderWriterInterface<RequestT, ResponseT> {
 public:
  MockReaderWriterT(Sequence* sequence) : sequence_(sequence) {
    EXPECT_CALL(*this, WritesDone(_)).Times(0);
    EXPECT_CALL(*this, ReadInitialMetadata(_)).Times(0);
    EXPECT_CALL(*this, Finish(_, _)).Times(0);
    EXPECT_CALL(*this, Write(_, _)).Times(0);
    EXPECT_CALL(*this, Write(_, _, _)).Times(0);
    EXPECT_CALL(*this, Read(_, _)).Times(0);
  }

  void ExpectRead(const GoogleString& asciiProto) {
    ResponseT resp;
    ASSERT_THAT(ParseTextFormatProtoFromString(asciiProto, &resp), Eq(true));

    EXPECT_CALL(*this, Read(_, _))
        .WillOnce(DoAll(
            SetArgPointee<0>(resp),
            WithArgs<1>(Invoke(this, &MockReaderWriterT::QueueVoidFunction))));
  }

  void ExpectReadFailure() {
    EXPECT_CALL(*this, Read(_, _))
        .WillOnce(WithArgs<1>(
            Invoke(this, &MockReaderWriterT::QueueVoidFunctionForCancel)));
  }

  // Matcher winds up being a complicated type that includes testing::internal
  // stuff, so we just template on it.
  template <typename Matcher>
  void ExpectWrite(const Matcher& matcher) {
    EXPECT_CALL(*this, Write(matcher, _))
        .WillOnce(
            WithArgs<1>(Invoke(this, &MockReaderWriterT::QueueVoidFunction)));
  }

  template <typename Matcher>
  void ExpectWriteFailure(const Matcher& matcher) {
    EXPECT_CALL(*this, Write(matcher, _))
        .WillOnce(WithArgs<1>(
            Invoke(this, &MockReaderWriterT::QueueVoidFunctionForCancel)));
  }

  void ExpectFinish(const ::grpc::Status& status) {
    EXPECT_CALL(*this, Finish(_, _))
        .WillOnce(DoAll(
            SetArgPointee<0>(status),
            WithArgs<1>(Invoke(this, &MockReaderWriterT::QueueVoidFunction))));
  }

  void ExpectFinishAndNotify(const ::grpc::Status& status,
                             WorkerTestBase::SyncPoint* sync) {
    EXPECT_CALL(*this, Finish(_, _))
        .WillOnce(DoAll(SetArgPointee<0>(status),
                        WithArgs<1>(Invoke([this, sync](void* f) {
                          this->QueueVoidFunctionWithNotify(f, sync);
                        }))));
  }

  void ExpectFinishFailure() {
    EXPECT_CALL(*this, Finish(_, _))
        .WillOnce(WithArgs<1>(
            Invoke(this, &MockReaderWriterT::QueueVoidFunctionForCancel)));
  }

  MOCK_METHOD1(WritesDone, void(void* tag));
  MOCK_METHOD1(ReadInitialMetadata, void(void* tag));
  MOCK_METHOD2(Finish, void(::grpc::Status* status, void* tag));
  MOCK_METHOD2_T(Write, void(const RequestT& resp, void* tag));
  MOCK_METHOD3_T(Write, void(const RequestT& resp, ::grpc::WriteOptions options, void* tag));
  MOCK_METHOD2_T(Read, void(ResponseT* resp, void* tag));

 private:
  void QueueVoidFunction(void* fv) {
    Function* f = static_cast<Function*>(fv);
    sequence_->Add(f);
  }

  void QueueVoidFunctionForCancel(void* fv) {
    Function* f = static_cast<Function*>(fv);
    sequence_->Add(MakeFunction(f, &Function::CallCancel));
  }

  void QueueVoidFunctionWithNotify(void* fv, WorkerTestBase::SyncPoint* sync) {
    Function* f = static_cast<Function*>(fv);
    sequence_->Add(new NotifyFunction(f, sync));
  }

  Sequence* sequence_;
};

// Mock for CentralControllerRpcServiceStub. Mostly used just to bootstrap
// a MockReaderWriterT, this also features deferred execution to mimic gRPC.

class MockCentralControllerRpcServiceStub
    : public grpc::CentralControllerRpcService::StubInterface {
 public:
  MockCentralControllerRpcServiceStub(Sequence* sequence)
      : sequence_(sequence) {
    EXPECT_CALL(*this, ScheduleExpensiveOperationRaw(_)).Times(0);
    EXPECT_CALL(*this, ScheduleRewriteRaw(_)).Times(0);
    EXPECT_CALL(*this, AsyncScheduleExpensiveOperationRaw(_, _, _)).Times(0);
    EXPECT_CALL(*this, AsyncScheduleRewriteRaw(_, _, _)).Times(0);
  }

  MOCK_METHOD1(
      ScheduleExpensiveOperationRaw,
      ::grpc::ClientReaderWriterInterface<
          ::net_instaweb::ScheduleExpensiveOperationRequest,
          ::net_instaweb::
              ScheduleExpensiveOperationResponse>*(::grpc::ClientContext*));

  MOCK_METHOD1(
      ScheduleRewriteRaw,
      ::grpc::ClientReaderWriterInterface<
          ::net_instaweb::ScheduleRewriteRequest,
          ::net_instaweb::ScheduleRewriteResponse>*(::grpc::ClientContext*));

  MOCK_METHOD3(
      AsyncScheduleExpensiveOperationRaw,
      ::grpc::ClientAsyncReaderWriterInterface<
          ::net_instaweb::ScheduleExpensiveOperationRequest,
          net_instaweb::
              ScheduleExpensiveOperationResponse>*(::grpc::ClientContext*,
                                                   ::grpc::CompletionQueue*,
                                                   void*));

  MOCK_METHOD3(
      AsyncScheduleRewriteRaw,
      ::grpc::ClientAsyncReaderWriterInterface<
          ::net_instaweb::ScheduleRewriteRequest,
          ::net_instaweb::ScheduleRewriteResponse>*(::grpc::ClientContext*,
                                                    ::grpc::CompletionQueue*,
                                                    void*));

  void ExpectAsyncScheduleExpensiveOperation(
      ::grpc::ClientAsyncReaderWriterInterface<
          ::net_instaweb::ScheduleExpensiveOperationRequest,
          ::net_instaweb::ScheduleExpensiveOperationResponse>* rw) {
    // Configure the stub to invoke the callback and return rw in response to
    // a client initiating a request.
    EXPECT_CALL(*this,
                AsyncScheduleExpensiveOperationRaw(_, nullptr /* queue */, _))
        .WillOnce(DoAll(WithArgs<2>(Invoke([this](void* fv) {
                          sequence_->Add(static_cast<Function*>(fv));
                        })),
                        Return(rw)));
  }

  void ExpectAsyncScheduleExpensiveOperationFailure(
      ::grpc::ClientAsyncReaderWriterInterface<
          ::net_instaweb::ScheduleExpensiveOperationRequest,
          ::net_instaweb::ScheduleExpensiveOperationResponse>* rw) {
    // Configure the stub to invoke the Cancel callback and return rw in
    // response to a client initiating a request.
    EXPECT_CALL(*this,
                AsyncScheduleExpensiveOperationRaw(_, nullptr /* queue */, _))
        .WillOnce(DoAll(WithArgs<2>(Invoke([this](void* fv) {
                          sequence_->Add(
                              MakeFunction(static_cast<Function*>(fv),
                                           &Function::CallCancel));
                        })),
                        Return(rw)));
  }

  void ExpectAsyncScheduleRewrite(
      ::grpc::ClientAsyncReaderWriterInterface<
          ::net_instaweb::ScheduleRewriteRequest,
          ::net_instaweb::ScheduleRewriteResponse>* rw) {
    // Configure the stub to invoke the callback and return rw in response to
    // a client initiating a request.
    EXPECT_CALL(*this,
                AsyncScheduleRewriteRaw(_, nullptr /* queue */, _))
        .WillOnce(DoAll(WithArgs<2>(Invoke([this](void* fv) {
                          sequence_->Add(static_cast<Function*>(fv));
                        })),
                        Return(rw)));
  }

  void ExpectAsyncScheduleRewriteFailure(
      ::grpc::ClientAsyncReaderWriterInterface<
          ::net_instaweb::ScheduleRewriteRequest,
          ::net_instaweb::ScheduleRewriteResponse>* rw) {
    // Configure the stub to invoke the Cancel callback and return rw in
    // response to a client initiating a request.
    EXPECT_CALL(*this,
                AsyncScheduleRewriteRaw(_, nullptr /* queue */, _))
        .WillOnce(DoAll(WithArgs<2>(Invoke([this](void* fv) {
                          sequence_->Add(
                              MakeFunction(static_cast<Function*>(fv),
                                           &Function::CallCancel));
                        })),
                        Return(rw)));
  }

 private:
  Sequence* sequence_;
};

}  // namespace net_instaweb

#endif  // PAGESPEED_CONTROLLER_CONTROLLER_GRPC_MOCKS_H_
