// Copyright 2014 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 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/error.h>
#include <weave/cloud.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 Cloud,
                               public NotificationDelegate,
                               public CloudCommandUpdateInterface {
 public:
  using CloudRequestCallback =
      base::Callback<void(const base::DictionaryValue& response)>;
  using CloudRequestErrorCallback = base::Callback<void(const Error* 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;

  // Cloud overrides.
  void AddOnRegistrationChangedCallback(
      const OnRegistrationChangedCallback& callback) override;
  void GetDeviceInfo(
      const OnCloudRequestCallback& success_callback,
      const OnCloudRequestErrorCallback& error_callback) override;
  std::string RegisterDevice(const std::string& ticket_id,
                             ErrorPtr* error) override;
  bool UpdateDeviceInfo(const std::string& name,
                        const std::string& description,
                        const std::string& location,
                        ErrorPtr* error) override;
  bool UpdateBaseConfig(const std::string& anonymous_access_role,
                        bool local_discovery_enabled,
                        bool local_pairing_enabled,
                        ErrorPtr* error) override;
  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) override;

  // Add callback to listen for changes in config.
  void AddOnConfigChangedCallback(const Config::OnChangedCallback& 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 base::Closure& on_success,
                     const base::Closure& on_error) override;

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

 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();
  // Notification called when ConnectToCloud() succeeds.
  void OnConnectedToCloud();

  // Forcibly refreshes the access token.
  void RefreshAccessToken(const base::Closure& success_callback,
                          const CloudRequestErrorCallback& error_callback);

  // Callbacks for RefreshAccessToken().
  void OnRefreshAccessTokenSuccess(
      const std::shared_ptr<base::Closure>& success_callback,
      const std::shared_ptr<CloudRequestErrorCallback>& error_callback,
      int id,
      const provider::HttpClient::Response& response);
  void OnRefreshAccessTokenError(
      const std::shared_ptr<base::Closure>& success_callback,
      const std::shared_ptr<CloudRequestErrorCallback>& error_callback,
      int id,
      const Error* 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(const std::string& method,
                      const std::string& url,
                      const base::DictionaryValue* body,
                      const CloudRequestCallback& success_callback,
                      const CloudRequestErrorCallback& error_callback);

  // Helper for DoCloudRequest().
  struct CloudRequestData {
    std::string method;
    std::string url;
    std::string body;
    CloudRequestCallback success_callback;
    CloudRequestErrorCallback error_callback;
  };
  void SendCloudRequest(const std::shared_ptr<const CloudRequestData>& data);
  void OnCloudRequestSuccess(
      const std::shared_ptr<const CloudRequestData>& data,
      int request_id,
      const provider::HttpClient::Response& response);
  void OnCloudRequestError(const std::shared_ptr<const CloudRequestData>& data,
                           int request_id,
                           const Error* error);
  void RetryCloudRequest(const std::shared_ptr<const CloudRequestData>& data);
  void OnAccessTokenRefreshed(
      const std::shared_ptr<const CloudRequestData>& data);
  void OnAccessTokenError(const std::shared_ptr<const CloudRequestData>& data,
                          const Error* error);
  void CheckAccessTokenError(const Error* error);

  void UpdateDeviceResource(const base::Closure& on_success,
                            const CloudRequestErrorCallback& on_failure);
  void StartQueuedUpdateDeviceResource();
  // Success/failure callbacks for UpdateDeviceResource().
  void OnUpdateDeviceResourceSuccess(const base::DictionaryValue& device_info);
  void OnUpdateDeviceResourceError(const Error* error);

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

  // 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&)>& on_success,
      const CloudRequestErrorCallback& on_failure);
  // Success/failure callbacks for FetchCommands().
  void OnFetchCommandsSuccess(
      const base::Callback<void(const base::ListValue&)>& callback,
      const base::DictionaryValue& json);
  void OnFetchCommandsError(const CloudRequestErrorCallback& callback,
                            const Error* error);
  // 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);

  void PublishCommands(const base::ListValue& commands);
  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 OnPublishStateSuccess(StateChangeQueueInterface::UpdateID update_id,
                             const base::DictionaryValue& reply);
  void OnPublishStateError(const Error* 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 SetRegistrationStatus(RegistrationStatus new_status);
  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();

  // 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<std::pair<base::Closure, CloudRequestErrorCallback>>;
  // Success/error callbacks for device resource update request currently in
  // flight to the cloud server.
  ResourceUpdateCallbackList in_progress_resource_update_callbacks_;
  // Success/error 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 current registration status.
  RegistrationStatus registration_status_{RegistrationStatus::kUnconfigured};

  std::vector<OnRegistrationChangedCallback> on_registration_changed_;

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

}  // namespace weave

#endif  // LIBWEAVE_SRC_DEVICE_REGISTRATION_INFO_H_
