// 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_PRIVET_PRIVET_HANDLER_H_
#define LIBWEAVE_SRC_PRIVET_PRIVET_HANDLER_H_

#include <map>
#include <string>
#include <utility>

#include <base/macros.h>
#include <base/memory/weak_ptr.h>
#include <base/scoped_observer.h>

#include "src/privet/cloud_delegate.h"

namespace base {
class Value;
class DictionaryValue;
}  // namespace base

namespace weave {
namespace privet {

class DeviceDelegate;
class IdentityDelegate;
class SecurityDelegate;
class WifiDelegate;

// Privet V3 HTTP/HTTPS requests handler.
// API details at https://developers.google.com/cloud-devices/
class PrivetHandler : public CloudDelegate::Observer {
 public:
  // Callback to handle requests asynchronously.
  // |status| is HTTP status code.
  // |output| is result returned in HTTP response. Contains result of
  // successfully request of information about error.
  using RequestCallback =
      base::Callback<void(int status, const base::DictionaryValue& output)>;

  PrivetHandler(CloudDelegate* cloud,
                DeviceDelegate* device,
                SecurityDelegate* pairing,
                WifiDelegate* wifi);
  ~PrivetHandler() override;

  void OnCommandDefsChanged() override;
  void OnStateChanged() override;

  std::vector<std::string> GetHttpPaths() const;
  std::vector<std::string> GetHttpsPaths() const;

  // Handles HTTP/HTTPS Privet request.
  // |api| is the path from the HTTP request, e.g /privet/info.
  // |auth_header| is the Authentication header from HTTP request.
  // |input| is the POST data from HTTP request. If nullptr, data format is
  // not valid JSON.
  // |callback| will be called exactly once during or after |HandleRequest|
  // call.
  void HandleRequest(const std::string& api,
                     const std::string& auth_header,
                     const base::DictionaryValue* input,
                     const RequestCallback& callback);

 private:
  using ApiHandler = void (PrivetHandler::*)(const base::DictionaryValue&,
                                             const UserInfo&,
                                             const RequestCallback&);

  // Adds a handler for both HTTP and HTTPS interfaces.
  void AddHandler(const std::string& path, ApiHandler handler, AuthScope scope);

  // Adds a handler for both HTTPS interface only.
  void AddSecureHandler(const std::string& path,
                        ApiHandler handler,
                        AuthScope scope);

  void HandleInfo(const base::DictionaryValue&,
                  const UserInfo& user_info,
                  const RequestCallback& callback);
  void HandlePairingStart(const base::DictionaryValue& input,
                          const UserInfo& user_info,
                          const RequestCallback& callback);
  void HandlePairingConfirm(const base::DictionaryValue& input,
                            const UserInfo& user_info,
                            const RequestCallback& callback);
  void HandlePairingCancel(const base::DictionaryValue& input,
                           const UserInfo& user_info,
                           const RequestCallback& callback);
  void HandleAuth(const base::DictionaryValue& input,
                  const UserInfo& user_info,
                  const RequestCallback& callback);
  void HandleSetupStart(const base::DictionaryValue& input,
                        const UserInfo& user_info,
                        const RequestCallback& callback);
  void HandleSetupStatus(const base::DictionaryValue&,
                         const UserInfo& user_info,
                         const RequestCallback& callback);
  void HandleState(const base::DictionaryValue& input,
                   const UserInfo& user_info,
                   const RequestCallback& callback);
  void HandleCommandDefs(const base::DictionaryValue& input,
                         const UserInfo& user_info,
                         const RequestCallback& callback);
  void HandleCommandsExecute(const base::DictionaryValue& input,
                             const UserInfo& user_info,
                             const RequestCallback& callback);
  void HandleCommandsStatus(const base::DictionaryValue& input,
                            const UserInfo& user_info,
                            const RequestCallback& callback);
  void HandleCommandsList(const base::DictionaryValue& input,
                          const UserInfo& user_info,
                          const RequestCallback& callback);
  void HandleCommandsCancel(const base::DictionaryValue& input,
                            const UserInfo& user_info,
                            const RequestCallback& callback);
  void HandleCheckForUpdates(const base::DictionaryValue& input,
                             const UserInfo& user_info,
                             const RequestCallback& callback);

  void ReplyWithSetupStatus(const RequestCallback& callback) const;
  void ReplyToUpdateRequest(const RequestCallback& callback) const;
  void OnUpdateRequestTimeout(int update_request_id);

  CloudDelegate* cloud_ = nullptr;
  DeviceDelegate* device_ = nullptr;
  SecurityDelegate* security_ = nullptr;
  WifiDelegate* wifi_ = nullptr;

  struct HandlerParameters {
    ApiHandler handler;
    AuthScope scope;
    bool https_only = true;
  };
  std::map<std::string, HandlerParameters> handlers_;

  struct UpdateRequestParameters {
    RequestCallback callback;
    int request_id = 0;
    int state_fingerprint = -1;
    int command_defs_fingerprint = -1;
  };
  std::vector<UpdateRequestParameters> update_requests_;
  int last_update_request_id_{0};

  uint64_t last_user_id_{0};
  int state_fingerprint_{0};
  int command_defs_fingerprint_{0};
  ScopedObserver<CloudDelegate, CloudDelegate::Observer> cloud_observer_{this};

  base::WeakPtrFactory<PrivetHandler> weak_ptr_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(PrivetHandler);
};

}  // namespace privet
}  // namespace weave

#endif  // LIBWEAVE_SRC_PRIVET_PRIVET_HANDLER_H_
