// 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 OnTraitDefsChanged() override;
  void OnStateChanged() override;
  void OnComponentTreeChanged() 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 HandleTraits(const base::DictionaryValue& input,
                    const UserInfo& user_info,
                    const RequestCallback& callback);
  void HandleComponents(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};
    uint64_t state_fingerprint{0};
    uint64_t traits_fingerprint{0};
    uint64_t components_fingerprint{0};
  };
  std::vector<UpdateRequestParameters> update_requests_;
  int last_update_request_id_{0};

  uint64_t last_user_id_{0};
  uint64_t state_fingerprint_{1};
  uint64_t traits_fingerprint_{1};
  uint64_t components_fingerprint_{1};
  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_
