// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SHILL_MOCK_ADAPTORS_H_
#define SHILL_MOCK_ADAPTORS_H_

#include <string>
#include <vector>

#include <gmock/gmock.h>

#include "shill/adaptor_interfaces.h"
#include "shill/error.h"

namespace shill {

// These are the functions that a Device adaptor must support
class DeviceMockAdaptor : public DeviceAdaptorInterface {
 public:
  static const char kRpcId[];
  static const char kRpcConnId[];

  DeviceMockAdaptor();
  ~DeviceMockAdaptor() override;
  const std::string &GetRpcIdentifier() override;
  const std::string &GetRpcConnectionIdentifier() override;

  MOCK_METHOD2(EmitBoolChanged, void(const std::string &name, bool value));
  MOCK_METHOD2(EmitUintChanged, void(const std::string &name, uint32_t value));
  MOCK_METHOD2(EmitUint16Changed,
               void(const std::string &name, uint16_t value));
  MOCK_METHOD2(EmitIntChanged, void(const std::string &name, int value));
  MOCK_METHOD2(EmitStringChanged, void(const std::string &name,
                                       const std::string &value));
  MOCK_METHOD2(EmitStringmapChanged, void(const std::string &name,
                                          const Stringmap &value));
  MOCK_METHOD2(EmitStringmapsChanged, void(const std::string &name,
                                           const Stringmaps &value));
  MOCK_METHOD2(EmitStringsChanged, void(const std::string &name,
                                        const Strings &value));
  MOCK_METHOD2(EmitKeyValueStoreChanged, void(const std::string &name,
                                              const KeyValueStore &value));
  MOCK_METHOD2(EmitRpcIdentifierChanged,
               void(const std::string &name,
                    const std::string &value));
  MOCK_METHOD2(EmitRpcIdentifierArrayChanged,
               void(const std::string &name,
                    const std::vector<std::string> &value));

 private:
  const std::string rpc_id_;
  const std::string rpc_conn_id_;
};

// These are the functions that a IPConfig adaptor must support
class IPConfigMockAdaptor : public IPConfigAdaptorInterface {
 public:
  static const char kRpcId[];

  IPConfigMockAdaptor();
  ~IPConfigMockAdaptor() override;
  const std::string &GetRpcIdentifier() override;

  MOCK_METHOD2(EmitBoolChanged, void(const std::string&, bool));
  MOCK_METHOD2(EmitUintChanged, void(const std::string&, uint32_t));
  MOCK_METHOD2(EmitIntChanged, void(const std::string&, int));
  MOCK_METHOD2(EmitStringChanged, void(const std::string&, const std::string&));
  MOCK_METHOD2(EmitStringsChanged,
               void(const std::string&, const std::vector<std::string>&));

 private:
  const std::string rpc_id_;
};

// These are the functions that a Manager adaptor must support
class ManagerMockAdaptor : public ManagerAdaptorInterface {
 public:
  static const char kRpcId[];

  ManagerMockAdaptor();
  ~ManagerMockAdaptor() override;
  const std::string &GetRpcIdentifier() override;

  MOCK_METHOD0(UpdateRunning, void(void));
  MOCK_METHOD2(EmitBoolChanged, void(const std::string&, bool));
  MOCK_METHOD2(EmitUintChanged, void(const std::string&, uint32_t));
  MOCK_METHOD2(EmitIntChanged, void(const std::string&, int));
  MOCK_METHOD2(EmitStringChanged, void(const std::string&, const std::string&));
  MOCK_METHOD2(EmitStringsChanged,
               void(const std::string &, const std::vector<std::string> &));
  MOCK_METHOD2(EmitRpcIdentifierChanged,
               void(const std::string &, const std::string &));
  MOCK_METHOD2(EmitRpcIdentifierArrayChanged,
               void(const std::string &, const std::vector<std::string> &));

  MOCK_METHOD1(EmitStateChanged, void(const std::string&));

 private:
  const std::string rpc_id_;
};

// These are the functions that a Profile adaptor must support
class ProfileMockAdaptor : public ProfileAdaptorInterface {
 public:
  static const char kRpcId[];

  ProfileMockAdaptor();
  ~ProfileMockAdaptor() override;
  const std::string &GetRpcIdentifier() override;

  MOCK_METHOD2(EmitBoolChanged, void(const std::string&, bool));
  MOCK_METHOD2(EmitUintChanged, void(const std::string&, uint32_t));
  MOCK_METHOD2(EmitIntChanged, void(const std::string&, int));
  MOCK_METHOD2(EmitStringChanged, void(const std::string&, const std::string&));

 private:
  const std::string rpc_id_;
};

// These are the functions that a Task adaptor must support
class RPCTaskMockAdaptor : public RPCTaskAdaptorInterface {
 public:
  static const char kRpcId[];
  static const char kRpcInterfaceId[];
  static const char kRpcConnId[];

  RPCTaskMockAdaptor();
  ~RPCTaskMockAdaptor() override;

  const std::string &GetRpcIdentifier() override;
  const std::string &GetRpcInterfaceIdentifier() override;
  const std::string &GetRpcConnectionIdentifier() override;

 private:
  const std::string rpc_id_;
  const std::string rpc_interface_id_;
  const std::string rpc_conn_id_;
};

// These are the functions that a Service adaptor must support
class ServiceMockAdaptor : public ServiceAdaptorInterface {
 public:
  static const char kRpcId[];

  ServiceMockAdaptor();
  ~ServiceMockAdaptor() override;
  const std::string &GetRpcIdentifier() override;

  MOCK_METHOD0(UpdateConnected, void());
  MOCK_METHOD2(EmitBoolChanged, void(const std::string &name, bool value));
  MOCK_METHOD2(EmitUint8Changed, void(const std::string &name, uint8_t value));
  MOCK_METHOD2(EmitUint16Changed,
               void(const std::string &name, uint16_t value));
  MOCK_METHOD2(EmitUint16sChanged, void(const std::string &name,
                                        const Uint16s &value));
  MOCK_METHOD2(EmitUintChanged, void(const std::string &name, uint32_t value));
  MOCK_METHOD2(EmitIntChanged, void(const std::string &name, int value));
  MOCK_METHOD2(EmitRpcIdentifierChanged,
               void(const std::string &name, const std::string &value));
  MOCK_METHOD2(EmitStringChanged,
               void(const std::string &name, const std::string &value));
  MOCK_METHOD2(EmitStringmapChanged,
               void(const std::string &name, const Stringmap &value));

 private:
  const std::string rpc_id_;
};

#ifndef DISABLE_VPN
class ThirdPartyVpnMockAdaptor : public ThirdPartyVpnAdaptorInterface {
 public:
  ThirdPartyVpnMockAdaptor();
  ~ThirdPartyVpnMockAdaptor() override;

  MOCK_METHOD1(EmitPacketReceived, void(const std::vector<uint8_t> &packet));

  MOCK_METHOD1(EmitPlatformMessage, void(uint32_t message));
};
#endif

}  // namespace shill

#endif  // SHILL_MOCK_ADAPTORS_H_
