// 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/component_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"

namespace base {
class DictionaryValue;
}  // namespace base

namespace weave {

class StateManager;

namespace provider {
class Network;
class TaskRunner;
}

namespace privet {
class AuthManager;
}

// 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(Config* config,
                         ComponentManager* component_manager,
                         provider::TaskRunner* task_runner,
                         provider::HttpClient* http_client,
                         provider::Network* network,
                         privet::AuthManager* auth_manager);

  ~DeviceRegistrationInfo() override;

  void AddGcdStateChangedCallback(
      const Device::GcdStateChangedCallback& callback);

  void RegisterDevice(RegistrationData registration_data,
                      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);

  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/weave/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/weave/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/weave/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();

  // 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_; }

  GcdState GetGcdState() const { return gcd_state_; }

  // Checks whether we have credentials generated during registration.
  bool HaveRegistrationCredentials() const;

 private:
  friend class DeviceRegistrationInfoTest;

  const Config::Settings& GetDefaults() const { return config_->GetDefaults(); }

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

  // Calls HaveRegistrationCredentials() and logs an error if no credentials
  // are available.
  bool VerifyRegistrationCredentials(ErrorPtr* error) const;

  // 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);

  void SendAuthInfo();
  void OnSendAuthInfoDone(const std::vector<uint8_t>& token,
                          const base::DictionaryValue& body,
                          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(ComponentManager::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() const;

  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 OnTraitDefsChanged();
  void OnComponentTreeChanged();
  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 RemoveCredentials();

  void RegisterDeviceError(const DoneCallback& callback, ErrorPtr error);
  void RegisterDeviceOnTicketSent(
      const RegistrationData& registration_data,
      const DoneCallback& callback,
      std::unique_ptr<provider::HttpClient::Response> response,
      ErrorPtr error);
  void RegisterDeviceOnTicketFinalized(
      const RegistrationData& registration_data,
      const DoneCallback& callback,
      std::unique_ptr<provider::HttpClient::Response> response,
      ErrorPtr error);
  void RegisterDeviceOnAuthCodeSent(
      const RegistrationData& registration_data,
      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};

  Config* config_{nullptr};

  // Global component manager.
  ComponentManager* component_manager_{nullptr};

  // 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_;

  bool auth_info_update_inprogress_{false};

  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};
  privet::AuthManager* auth_manager_{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_
