// Copyright 2016 The Fuchsia 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 PERIDOT_LIB_FIREBASE_FIREBASE_IMPL_H_
#define PERIDOT_LIB_FIREBASE_FIREBASE_IMPL_H_

#include <functional>
#include <memory>
#include <string>
#include <vector>

#include <lib/callback/auto_cleanable.h>
#include <lib/callback/cancellable.h>
#include <lib/fit/function.h>
#include <lib/network_wrapper/network_wrapper.h>
#include <rapidjson/document.h>

#include "peridot/lib/firebase/event_stream.h"
#include "peridot/lib/firebase/firebase.h"
#include "peridot/lib/firebase/status.h"
#include "peridot/lib/firebase/watch_client.h"
#include "peridot/lib/socket/socket_drainer_client.h"

namespace firebase {

class FirebaseImpl : public Firebase {
 public:
  // |db_id| is the identifier of the Firebase Realtime Database instance. E.g.,
  // if the database is hosted at https://example.firebaseio.com/, its
  // identifier is "example".
  //
  // |prefix| is a url prefix against which all requests will be made, without a
  // leading or trailing slash. (possible with slashes inside) If empty,
  // requests will be made against root of the database.
  FirebaseImpl(network_wrapper::NetworkWrapper* network_wrapper, const std::string& db_id,
               const std::string& prefix);
  ~FirebaseImpl() override;

  // Firebase:
  void Get(const std::string& key, const std::vector<std::string>& query_params,
           fit::function<void(Status status, std::unique_ptr<rapidjson::Value> value)> callback)
      override;
  void Put(const std::string& key, const std::vector<std::string>& query_params,
           const std::string& data, fit::function<void(Status status)> callback) override;
  void Patch(const std::string& key, const std::vector<std::string>& query_params,
             const std::string& data, fit::function<void(Status status)> callback) override;
  void Delete(const std::string& key, const std::vector<std::string>& query_params,
              fit::function<void(Status status)> callback) override;
  void Watch(const std::string& key, const std::vector<std::string>& query_params,
             WatchClient* watch_client) override;
  void UnWatch(WatchClient* watch_client) override;

  const std::string& api_url() { return api_url_; }

 private:
  std::string BuildApiUrl(const std::string& db_id, const std::string& prefix);

  std::string BuildRequestUrl(const std::string& key,
                              const std::vector<std::string>& query_params) const;

  void Request(const std::string& url, const std::string& method, const std::string& message,
               fit::function<void(Status status, std::string response)> callback);

  void OnResponse(fit::function<void(Status status, std::string response)> callback,
                  ::fuchsia::net::oldhttp::URLResponse response);

  void OnStream(WatchClient* watch_client, ::fuchsia::net::oldhttp::URLResponse response);

  void OnStreamComplete(WatchClient* watch_client);

  void OnStreamEvent(WatchClient* watch_client, Status status, const std::string& event,
                     const std::string& payload);

  void HandleMalformedEvent(WatchClient* watch_client, const std::string& event,
                            const std::string& payload, const char error_description[]);

  network_wrapper::NetworkWrapper* const network_wrapper_;
  // Api url against which requests are made, without a trailing slash.
  const std::string api_url_;

  callback::CancellableContainer requests_;
  callback::AutoCleanableSet<socket::SocketDrainerClient> drainers_;

  struct WatchData;
  std::map<WatchClient*, std::unique_ptr<WatchData>> watch_data_;
};

}  // namespace firebase

#endif  // PERIDOT_LIB_FIREBASE_FIREBASE_IMPL_H_
