// 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,
      const std::string& reason);
  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().
  // |backup_fetch| is set to true when performing backup ("just-in-case")
  // command fetch while XMPP channel is up and running.
  void FetchAndPublishCommands(const std::string& reason);

  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,
                        const std::string& channel_name) 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};
  // Specifies the reason for queued command fetch request.
  std::string queued_fetch_reason_;

  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_
