// Copyright 2021 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 MINIOS_NETWORK_MANAGER_H_
#define MINIOS_NETWORK_MANAGER_H_

#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include <base/memory/weak_ptr.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "minios/network_manager_interface.h"
#include "minios/shill_proxy_interface.h"

namespace minios {

class NetworkManager : public NetworkManagerInterface {
 public:
  // The delay in milliseconds before retrying connection to network.
  static const int kConnectionRetryMsDelay = 500;

  explicit NetworkManager(std::unique_ptr<ShillProxyInterface> shill_proxy);
  virtual ~NetworkManager() = default;

  NetworkManager(const NetworkManager&) = delete;
  NetworkManager& operator=(const NetworkManager&) = delete;

  // NetworkManagerInterface overrides.
  void Connect(const std::string& ssid, const std::string& passphrase) override;
  void GetNetworks() override;

 private:
  friend class NetworkManagerTest;
  FRIEND_TEST(NetworkManagerTest, Connect);
  FRIEND_TEST(NetworkManagerTest, Connect_RequestScanSuccess_NoPassphrase);
  FRIEND_TEST(NetworkManagerTest, Connect_RequestScanSuccess_Passphrase);
  FRIEND_TEST(NetworkManagerTest, Connect_GetServiceSuccess_GoodStrength);
  FRIEND_TEST(NetworkManagerTest, Connect_GetServiceSuccess_BadStrength);
  FRIEND_TEST(NetworkManagerTest, Connect_GetServiceSuccess_MissingStrength);
  FRIEND_TEST(NetworkManagerTest,
              Connect_ConnectToNetworkError_InProgressRetriesConnection);
  FRIEND_TEST(NetworkManagerTest,
              Connect_ConnectToNetworkError_AlreadyConnected);
  FRIEND_TEST(NetworkManagerTest,
              Connect_ConnectToNetworkError_OtherErrorResponsesFromShill);
  FRIEND_TEST(NetworkManagerTest, GetNetworks);
  FRIEND_TEST(NetworkManagerTest, GetGlobalPropertiesSuccess_MultipleServices);
  FRIEND_TEST(NetworkManagerTest, GetGlobalPropertiesSuccess_EmptyServices);
  FRIEND_TEST(NetworkManagerTest,
              IterateOverServicePropertiesSuccess_EmptyServices);
  FRIEND_TEST(NetworkManagerTest,
              IterateOverServicePropertiesSuccess_OneService);
  FRIEND_TEST(NetworkManagerTest,
              IterateOverServicePropertiesSuccess_MoreServicesToIterate);
  FRIEND_TEST(NetworkManagerTest,
              IterateOverServicePropertiesError_MoreServicesToIterate);
  FRIEND_TEST(NetworkManagerTest,
              IterateOverServicePropertiesError_AlwaysReturnOnEnd);

  typedef struct {
    std::string passphrase;
    // The service path for the SSID.
    dbus::ObjectPath service_path;
  } ConnectField;
  // Mapping from SSID to `ConnectField`.
  using ConnectMapType = std::unordered_map<std::string, ConnectField>;
  using ConnectMapIter = ConnectMapType::iterator;

  typedef struct {
    // The scanned list of services to go over.
    std::vector<dbus::ObjectPath> service_paths;
    // The network names that is built up.
    std::vector<std::string> networks;
  } GetNetworksField;
  using GetNetworksListType = std::vector<GetNetworksField>;
  using GetNetworksListIter = GetNetworksListType::iterator;

  // Member function types for `*RequestScan()`s.
  using ConnectRequestScanSuccessType =
      void (NetworkManager::*)(ConnectMapIter);
  using ConnectRequestScanErrorType = void (NetworkManager::*)(ConnectMapIter,
                                                               brillo::Error*);
  using GetNetworksRequestScanSuccessType =
      void (NetworkManager::*)(GetNetworksListIter);
  using GetNetworksRequestScanErrorType =
      void (NetworkManager::*)(GetNetworksListIter, brillo::Error*);

  // `Connect()` sequence.
  // `ManagerRequestScan()` callbacks.
  void RequestScanSuccess(ConnectMapIter iter);
  void RequestScanError(ConnectMapIter iter, brillo::Error* error);
  // `ManagerFindMatchingService()` callbacks.
  void FindServiceSuccess(ConnectMapIter iter,
                          const dbus::ObjectPath& service_path);
  void FindServiceError(ConnectMapIter iter, brillo::Error* error);
  // `ServiceGetProperties()` callbacks.
  void GetServiceSuccess(ConnectMapIter iter,
                         const brillo::VariantDictionary& dict);
  void GetServiceError(ConnectMapIter iter, brillo::Error* error);
  // `ServiceSetProperties()` callbacks.
  void ConfigureNetworkSuccess(ConnectMapIter iter);
  void ConfigureNetworkError(ConnectMapIter iter, brillo::Error* error);
  void ServiceConnect(ConnectMapIter iter);
  // `ServiceConnect()` callbacks.
  void ConnectToNetworkSuccess(ConnectMapIter iter);
  void ConnectToNetworkError(ConnectMapIter iter, brillo::Error* error);
  // Response helpers for `ConnectMapIter`.
  void Return(ConnectMapIter iter, brillo::Error* error = nullptr);

  // `GetNetworks()` sequence.
  // `ManagerRequestScan()` callbacks.
  void RequestScanSuccess(GetNetworksListIter iter);
  void RequestScanError(GetNetworksListIter iter, brillo::Error* error);
  // `ManagerGetProperties()` callbacks.
  void GetGlobalPropertiesSuccess(GetNetworksListIter iter,
                                  const brillo::VariantDictionary& dict);
  void GetGlobalPropertiesError(GetNetworksListIter iter, brillo::Error* error);
  // `ServiceGetProperties()` callbacks.
  void IterateOverServicePropertiesSuccess(
      GetNetworksListIter iter, const brillo::VariantDictionary& dict);
  void IterateOverServicePropertiesError(GetNetworksListIter iter,
                                         brillo::Error* error);
  // Response helpers for `GetNetworksListIter`.
  void Return(GetNetworksListIter iter, brillo::Error* error = nullptr);

  ConnectMapType connect_map_;
  GetNetworksListType get_networks_list_;

  std::unique_ptr<ShillProxyInterface> shill_proxy_;

  base::WeakPtrFactory<NetworkManager> weak_ptr_factory_;
};

}  // namespace minios

#endif  // MINIOS_NETWORK_MANAGER_H__
