// Copyright 2018 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_VPN_THIRD_PARTY_VPN_DRIVER_H_
#define SHILL_VPN_THIRD_PARTY_VPN_DRIVER_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <base/callback.h>
#include <gtest/gtest_prod.h>

#include "shill/default_service_observer.h"
#include "shill/ipconfig.h"
#include "shill/net/io_handler.h"
#include "shill/refptr_types.h"
#include "shill/service.h"
#include "shill/vpn/vpn_driver.h"

namespace shill {

class Error;
class FileIO;
class IOHandlerFactory;
class ThirdPartyVpnAdaptorInterface;

class ThirdPartyVpnDriver : public VPNDriver, public DefaultServiceObserver {
 public:
  enum PlatformMessage {
    kConnected = 1,
    kDisconnected,
    kError,
    kLinkDown,
    kLinkUp,
    kLinkChanged,
    kSuspend,
    kResume
  };

  ThirdPartyVpnDriver(Manager* manager, ProcessManager* process_manager);
  ~ThirdPartyVpnDriver() override;

  // UpdateConnectionState is called by DBus adaptor when
  // "UpdateConnectionState" method is called on the DBus interface.
  void UpdateConnectionState(Service::ConnectState connection_state,
                             std::string* error_message);

  // SendPacket is called by the DBus adaptor when "SendPacket" method is called
  // on the DBus interface.
  void SendPacket(const std::vector<uint8_t>& data, std::string* error_message);

  // SetParameters is called by the DBus adaptor when "SetParameter" method is
  // called on the DBus interface.
  void SetParameters(const std::map<std::string, std::string>& parameters,
                     std::string* error_message,
                     std::string* warning_message);

  void ClearExtensionId(Error* error);
  bool SetExtensionId(const std::string& value, Error* error);

  // Implementation of VPNDriver
  void InitPropertyStore(PropertyStore* store) override;
  void ConnectAsync(const VPNService::DriverEventCallback& callback) override;
  IPConfig::Properties GetIPProperties() const override;
  std::string GetProviderType() const override;
  IfType GetIfType() const override;
  void Disconnect() override;

  // Implements DefaultServiceObserver.
  void OnDefaultServiceChanged(const ServiceRefPtr& logical_service,
                               bool logical_service_changed,
                               const ServiceRefPtr& physical_service,
                               bool physical_service_changed) override;

  void OnDefaultServiceStateChanged(const ServiceRefPtr& service) override;
  bool Load(const StoreInterface* storage,
            const std::string& storage_id) override;
  bool Save(StoreInterface* storage,
            const std::string& storage_id,
            bool save_credentials) override;

  void OnBeforeSuspend(const ResultCallback& callback) override;
  void OnAfterResume() override;

  const std::string& object_path_suffix() const { return object_path_suffix_; }

 protected:
  void OnConnectTimeout() override;

 private:
  friend class ThirdPartyVpnDriverTest;
  FRIEND_TEST(ThirdPartyVpnDriverTest, ConnectAndDisconnect);
  FRIEND_TEST(ThirdPartyVpnDriverTest, ReconnectionEvents);
  FRIEND_TEST(ThirdPartyVpnDriverTest, PowerEvents);
  FRIEND_TEST(ThirdPartyVpnDriverTest, SetParameters);
  FRIEND_TEST(ThirdPartyVpnDriverTest, UpdateConnectionState);
  FRIEND_TEST(ThirdPartyVpnDriverTest, SendPacket);

  // Resets the internal state and deallocates all resources - closes the
  // handle to tun device, IO handler if open and deactivates itself with the
  // |thirdpartyvpn_adaptor_| if active.
  void Cleanup();

  // First do Cleanup(). Then if there's a service associated through
  // ConnectAsync, notify it to sets its state to Service::kStateFailure, sets
  // the failure reason to |failure|, sets its ErrorDetails property to
  // |error_details|, and disassociates from the service.
  void FailService(Service::ConnectFailure failure,
                   const std::string& error_details);

  // This function first checks if a value is present for a particular |key| in
  // the dictionary |parameters|.
  // If present it ensures the value is a valid IP address and then sets it to
  // the |target|.
  // The flag |mandatory| when set to true, makes the function treat a missing
  // key as an error. The function adds to |error_messages|, when there is a
  // failure.
  // This function supports only IPV4 addresses now.
  void ProcessIp(const std::map<std::string, std::string>& parameters,
                 const char* key,
                 std::string* target,
                 bool mandatory,
                 std::string* error_message);

  // This function first checks if a value is present for a particular |key| in
  // the dictionary |parameters|.
  // If present it treats the value as a list of string separated by
  // |delimiter|. Each string value is verified to be a valid IP address,
  // deleting ones that are not. The list of string is set to |target|.
  // The flag |mandatory| when set to true, makes the function treat a missing
  // key as an error. The function adds to |error_message|, when there is a
  // failure and |warn_message| when there is a warning.
  void ProcessIPArray(const std::map<std::string, std::string>& parameters,
                      const char* key,
                      char delimiter,
                      std::vector<std::string>* target,
                      bool mandatory,
                      std::string* error_message,
                      std::string* warn_message);

  // This function first checks if a value is present for a particular |key| in
  // the dictionary |parameters|.
  // If present it treats the value as a list of string separated by
  // |delimiter|. Each string value is verified to be a valid IP address in
  // CIDR format, deleting ones that are not. The list of string is set to
  // |target|. The flag |mandatory| when set to true, makes the function treat a
  // missing key as an error. The function adds to |error_message|, when there
  // is a failure and |warn_message| when there is a warning.
  void ProcessIPArrayCIDR(const std::map<std::string, std::string>& parameters,
                          const char* key,
                          char delimiter,
                          std::vector<std::string>* target,
                          bool mandatory,
                          std::string* error_message,
                          std::string* warn_message);

  // This function first checks if a value is present for a particular |key| in
  // the dictionary |parameters|.
  // If present it treats the value as a list of string separated by
  // |delimiter|. The list of string is set to |target|.
  // The flag |mandatory| when set to true, makes the function treat a missing
  // key as an error. The function adds to |error_messages|, when there is a
  // failure.
  void ProcessSearchDomainArray(
      const std::map<std::string, std::string>& parameters,
      const char* key,
      char delimiter,
      std::vector<std::string>* target,
      bool mandatory,
      std::string* error_message);

  // This function first checks if a value is present for a particular |key| in
  // the dictionary |parameters|.
  // If present it treats the value as an integer and verifies if the value lies
  // between |min_value| and |max_value|. It then updates |target| with the
  // integer value if it is in range.
  // The flag |mandatory| when set to true, makes the function treat a missing
  // key as an error. The function adds to |error_messages|, when there is a
  // failure.
  void ProcessInt32(const std::map<std::string, std::string>& parameters,
                    const char* key,
                    int32_t* target,
                    int32_t min_value,
                    int32_t max_value,
                    bool mandatory,
                    std::string* error_message);

  // This function first checks if a value is present for a particular |key| in
  // the dictionary |parameters|.
  // If present it treats the value as a boolean. It then updates |target|
  // with the boolean value if it is valid;
  // The flag |mandatory| when set to true, makes the function treat a missing
  // key as an error. The function adds to |error_messages|, when there is a
  // failure.
  void ProcessBoolean(const std::map<std::string, std::string>& parameters,
                      const char* key,
                      bool* target,
                      bool mandatory,
                      std::string* error_message);

  // These functions are called whe there is input and error in the tun
  // interface.
  void OnInput(InputData* data);
  void OnInputError(const std::string& error);

  // This function is called when a new default service first comes online,
  // so the app knows it needs to reconnect to the VPN gateway.
  void TriggerReconnect(const ServiceRefPtr& service);

  static const Property kProperties[];

  // This variable keeps track of the active instance. There can be multiple
  // instance of this class at a time but only one would be active that can
  // communicate with the VPN client over DBUS.
  static ThirdPartyVpnDriver* active_client_;

  // ThirdPartyVpnAdaptorInterface manages the DBus communication and provides
  // an unique identifier for the ThirdPartyVpnDriver.
  std::unique_ptr<ThirdPartyVpnAdaptorInterface> adaptor_interface_;

  // Object path suffix is made of Extension ID and name that collectively
  // identifies the configuration of the third party VPN client.
  std::string object_path_suffix_;

  // File descriptor for the tun device.
  int tun_fd_;

  // Configuration properties of the virtual VPN device set by the VPN client.
  IPConfig::Properties ip_properties_;
  bool ip_properties_set_;

  IOHandlerFactory* io_handler_factory_;

  // IO handler triggered when there is an error or data ready for read in the
  // tun device.
  std::unique_ptr<IOHandler> io_handler_;

  // The object is used to write to tun device.
  FileIO* file_io_;

  // Set used to identify duplicate entries in inclusion and exclusion list.
  std::set<std::string> known_cidrs_;

  // The boolean indicates if parameters are expected from the VPN client.
  bool parameters_expected_;

  // Flag indicating whether the extension supports reconnections - a feature
  // that wasn't in the original API.  If not, we won't send link_* or
  // suspend/resume signals.
  bool reconnect_supported_;

  // Helps distinguish between a network->network transition (where the
  // client simply reconnects), and a network->link_down->network transition
  // (where the client should disconnect, wait for link up, then reconnect).
  bool link_down_;

  VPNService::DriverEventCallback service_callback_;

  base::WeakPtrFactory<ThirdPartyVpnDriver> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(ThirdPartyVpnDriver);
};

}  // namespace shill

#endif  // SHILL_VPN_THIRD_PARTY_VPN_DRIVER_H_
