// Copyright 2015 The Weave 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 LIBWEAVE_SRC_DEVICE_REGISTRATION_INFO_H_
#define LIBWEAVE_SRC_DEVICE_REGISTRATION_INFO_H_

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

#include <base/callback.h>
#include <base/macros.h>
#include <base/memory/weak_ptr.h>
#include <base/time/time.h>
#include <weave/device.h>
#include <weave/error.h>
#include <weave/provider/http_client.h>

#include "src/backoff_entry.h"
#include "src/commands/cloud_command_update_interface.h"
#include "src/commands/command_manager.h"
#include "src/config.h"
#include "src/data_encoding.h"
#include "src/notification/notification_channel.h"
#include "src/notification/notification_delegate.h"
#include "src/notification/pull_channel.h"
#include "src/states/state_change_queue_interface.h"

namespace base {
class DictionaryValue;
}  // namespace base

namespace weave {

class StateManager;

namespace provider {
class Network;
class TaskRunner;
}

extern const char kErrorDomainOAuth2[];
extern const char kErrorDomainGCD[];
extern const char kErrorDomainGCDServer[];

// The DeviceRegistrationInfo class represents device registration information.
class DeviceRegistrationInfo : public NotificationDelegate,
                               public CloudCommandUpdateInterface {
 public:
  using CloudRequestDoneCallback =
      base::Callback<void(const base::DictionaryValue& response,
                          ErrorPtr error)>;

  DeviceRegistrationInfo(const std::shared_ptr<CommandManager>& command_manager,
                         const std::shared_ptr<StateManager>& state_manager,
                         std::unique_ptr<Config> config,
                         provider::TaskRunner* task_runner,
                         provider::HttpClient* http_client,
                         provider::Network* network);

  ~DeviceRegistrationInfo() override;

  void AddGcdStateChangedCallback(
      const Device::GcdStateChangedCallback& callback);
  void RegisterDevice(const std::string& ticket_id,
                      const DoneCallback& callback);

  void UpdateDeviceInfo(const std::string& name,
                        const std::string& description,
                        const std::string& location);
  void UpdateBaseConfig(AuthScope anonymous_access_role,
                        bool local_discovery_enabled,
                        bool local_pairing_enabled);
  bool UpdateServiceConfig(const std::string& client_id,
                           const std::string& client_secret,
                           const std::string& api_key,
                           const std::string& oauth_url,
                           const std::string& service_url,
                           ErrorPtr* error);

  void GetDeviceInfo(const CloudRequestDoneCallback& callback);

  // Returns the GCD service request URL. If |subpath| is specified, it is
  // appended to the base URL which is normally
  //    https://www.googleapis.com/clouddevices/v1/".
  // If |params| are specified, each key-value pair is formatted using
  // WebParamsEncode() and appended to URL as a query
  // string.
  // So, calling:
  //    GetServiceURL("ticket", {{"key","apiKey"}})
  // will return something like:
  //    https://www.googleapis.com/clouddevices/v1/ticket?key=apiKey
  std::string GetServiceURL(const std::string& subpath = {},
                            const WebParamList& params = {}) const;

  // Returns a service URL to access the registered device on GCD server.
  // The base URL used to construct the full URL looks like this:
  //    https://www.googleapis.com/clouddevices/v1/devices/<cloud_id>/
  std::string GetDeviceURL(const std::string& subpath = {},
                           const WebParamList& params = {}) const;

  // Similar to GetServiceURL, GetOAuthURL() returns a URL of OAuth 2.0 server.
  // The base URL used is https://accounts.google.com/o/oauth2/.
  std::string GetOAuthURL(const std::string& subpath = {},
                          const WebParamList& params = {}) const;

  // Starts GCD device if credentials available.
  void Start();

  // Checks whether we have credentials generated during registration.
  bool HaveRegistrationCredentials() const;
  // Calls HaveRegistrationCredentials() and logs an error if no credentials
  // are available.
  bool VerifyRegistrationCredentials(ErrorPtr* error) const;

  // Updates a command (override from CloudCommandUpdateInterface).
  void UpdateCommand(const std::string& command_id,
                     const base::DictionaryValue& command_patch,
                     const DoneCallback& callback) override;

  // TODO(vitalybuka): remove getters and pass config to dependent code.
  const Config::Settings& GetSettings() const { return config_->GetSettings(); }
  Config* GetMutableConfig() { return config_.get(); }

  GcdState GetGcdState() const { return gcd_state_; }

 private:
  friend class DeviceRegistrationInfoTest;

  base::WeakPtr<DeviceRegistrationInfo> AsWeakPtr() {
    return weak_factory_.GetWeakPtr();
  }

  // Cause DeviceRegistrationInfo to attempt to connect to cloud server on
  // its own later.
  void ScheduleCloudConnection(const base::TimeDelta& delay);

  // Initiates the connection to the cloud server.
  // Device will do required start up chores and then start to listen
  // to new commands.
  void ConnectToCloud(ErrorPtr error);
  // Notification called when ConnectToCloud() succeeds.
  void OnConnectedToCloud(ErrorPtr error);

  // Forcibly refreshes the access token.
  void RefreshAccessToken(const DoneCallback& callback);

  // Callbacks for RefreshAccessToken().
  void OnRefreshAccessTokenDone(
      const DoneCallback& callback,
      std::unique_ptr<provider::HttpClient::Response> response,
      ErrorPtr error);

  // Parse the OAuth response, and sets registration status to
  // kInvalidCredentials if our registration is no longer valid.
  std::unique_ptr<base::DictionaryValue> ParseOAuthResponse(
      const provider::HttpClient::Response& response,
      ErrorPtr* error);

  // This attempts to open a notification channel. The channel needs to be
  // restarted anytime the access_token is refreshed.
  void StartNotificationChannel();

  // Do a HTTPS request to cloud services.
  // Handles many cases like reauthorization, 5xx HTTP response codes
  // and device removal.  It is a recommended way to do cloud API
  // requests.
  // TODO(antonm): Consider moving into some other class.
  void DoCloudRequest(provider::HttpClient::Method method,
                      const std::string& url,
                      const base::DictionaryValue* body,
                      const CloudRequestDoneCallback& callback);

  // Helper for DoCloudRequest().
  struct CloudRequestData {
    provider::HttpClient::Method method;
    std::string url;
    std::string body;
    CloudRequestDoneCallback callback;
  };
  void SendCloudRequest(const std::shared_ptr<const CloudRequestData>& data);
  void OnCloudRequestDone(
      const std::shared_ptr<const CloudRequestData>& data,
      std::unique_ptr<provider::HttpClient::Response> response,
      ErrorPtr error);
  void RetryCloudRequest(const std::shared_ptr<const CloudRequestData>& data);
  void OnAccessTokenRefreshed(
      const std::shared_ptr<const CloudRequestData>& data,
      ErrorPtr error);
  void CheckAccessTokenError(ErrorPtr error);

  void UpdateDeviceResource(const DoneCallback& callback);
  void StartQueuedUpdateDeviceResource();
  void OnUpdateDeviceResourceDone(const base::DictionaryValue& device_info,
                                  ErrorPtr error);
  void OnUpdateDeviceResourceError(ErrorPtr error);

  // Callback from GetDeviceInfo() to retrieve the device resource timestamp
  // and retry UpdateDeviceResource() call.
  void OnDeviceInfoRetrieved(const base::DictionaryValue& device_info,
                             ErrorPtr error);

  // Extracts the timestamp from the device resource and sets it to
  // |last_device_resource_updated_timestamp_|.
  // Returns false if the "lastUpdateTimeMs" field is not found in the device
  // resource or it is invalid.
  bool UpdateDeviceInfoTimestamp(const base::DictionaryValue& device_info);

  void FetchCommands(
      const base::Callback<void(const base::ListValue&, ErrorPtr)>& callback);
  void OnFetchCommandsDone(
      const base::Callback<void(const base::ListValue&, ErrorPtr)>& callback,
      const base::DictionaryValue& json,
      ErrorPtr);
  // Called when FetchCommands completes (with either success or error).
  // This method reschedules any pending/queued fetch requests.
  void OnFetchCommandsReturned();

  // Processes the command list that is fetched from the server on connection.
  // Aborts commands which are in transitional states and publishes queued
  // commands which are queued.
  void ProcessInitialCommandList(const base::ListValue& commands,
                                 ErrorPtr error);

  void PublishCommands(const base::ListValue& commands, ErrorPtr error);
  void PublishCommand(const base::DictionaryValue& command);

  // Helper function to pull the pending command list from the server using
  // FetchCommands() and make them available on D-Bus with PublishCommands().
  void FetchAndPublishCommands();

  void PublishStateUpdates();
  void OnPublishStateDone(StateChangeQueueInterface::UpdateID update_id,
                          const base::DictionaryValue& reply,
                          ErrorPtr error);
  void OnPublishStateError(ErrorPtr error);

  // If unrecoverable error occurred (e.g. error parsing command instance),
  // notify the server that the command is aborted by the device.
  void NotifyCommandAborted(const std::string& command_id, ErrorPtr error);

  // Builds Cloud API devices collection REST resource which matches
  // current state of the device including command definitions
  // for all supported commands and current device state.
  std::unique_ptr<base::DictionaryValue> BuildDeviceResource(ErrorPtr* error);

  void SetGcdState(GcdState new_state);
  void SetDeviceId(const std::string& cloud_id);

  // Callback called when command definitions are changed to re-publish new CDD.
  void OnCommandDefsChanged();
  void OnStateChanged();

  // Overrides from NotificationDelegate.
  void OnConnected(const std::string& channel_name) override;
  void OnDisconnected() override;
  void OnPermanentFailure() override;
  void OnCommandCreated(const base::DictionaryValue& command) override;
  void OnDeviceDeleted(const std::string& cloud_id) override;

  // Wipes out the device registration information and stops server connections.
  void MarkDeviceUnregistered();

  void RegisterDeviceError(const DoneCallback& callback, ErrorPtr error);
  void RegisterDeviceOnTicketSent(
      const std::string& ticket_id,
      const DoneCallback& callback,
      std::unique_ptr<provider::HttpClient::Response> response,
      ErrorPtr error);
  void RegisterDeviceOnTicketFinalized(
      const DoneCallback& callback,
      std::unique_ptr<provider::HttpClient::Response> response,
      ErrorPtr error);
  void RegisterDeviceOnAuthCodeSent(
      const std::string& cloud_id,
      const std::string& robot_account,
      const DoneCallback& callback,
      std::unique_ptr<provider::HttpClient::Response> response,
      ErrorPtr error);

  // Transient data
  std::string access_token_;
  base::Time access_token_expiration_;
  // The time stamp of last device resource update on the server.
  std::string last_device_resource_updated_timestamp_;
  // Set to true if the device has connected to the cloud server correctly.
  // At this point, normal state and command updates can be dispatched to the
  // server.
  bool connected_to_cloud_{false};

  // HTTP transport used for communications.
  provider::HttpClient* http_client_{nullptr};

  provider::TaskRunner* task_runner_{nullptr};
  // Global command manager.
  std::shared_ptr<CommandManager> command_manager_;
  // Device state manager.
  std::shared_ptr<StateManager> state_manager_;

  std::unique_ptr<Config> config_;

  // Backoff manager for DoCloudRequest() method.
  std::unique_ptr<BackoffEntry::Policy> cloud_backoff_policy_;
  std::unique_ptr<BackoffEntry> cloud_backoff_entry_;
  std::unique_ptr<BackoffEntry> oauth2_backoff_entry_;

  // Flag set to true while a device state update patch request is in flight
  // to the cloud server.
  bool device_state_update_pending_{false};

  // Set to true when command queue fetch request is in flight to the server.
  bool fetch_commands_request_sent_{false};
  // Set to true when another command queue fetch request is queued while
  // another one was in flight.
  bool fetch_commands_request_queued_{false};

  using ResourceUpdateCallbackList = std::vector<DoneCallback>;
  // Callbacks for device resource update request currently in flight to the
  // cloud server.
  ResourceUpdateCallbackList in_progress_resource_update_callbacks_;
  // Callbacks for device resource update requests queued while another request
  // is in flight to the cloud server.
  ResourceUpdateCallbackList queued_resource_update_callbacks_;

  std::unique_ptr<NotificationChannel> primary_notification_channel_;
  std::unique_ptr<PullChannel> pull_channel_;
  NotificationChannel* current_notification_channel_{nullptr};
  bool notification_channel_starting_{false};

  provider::Network* network_{nullptr};

  // Tracks our GCD state.
  GcdState gcd_state_{GcdState::kUnconfigured};

  std::vector<Device::GcdStateChangedCallback> gcd_state_changed_callbacks_;

  base::WeakPtrFactory<DeviceRegistrationInfo> weak_factory_{this};
  DISALLOW_COPY_AND_ASSIGN(DeviceRegistrationInfo);
};

}  // namespace weave

#endif  // LIBWEAVE_SRC_DEVICE_REGISTRATION_INFO_H_
