// Copyright 2019 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 SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_SYMBOL_SERVER_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_SYMBOL_SERVER_H_

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

#include "lib/fit/function.h"
#include "src/developer/debug/zxdb/client/client_object.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/symbols/debug_symbol_file_type.h"

namespace zxdb {

class SymbolServer : public ClientObject {
 public:
  // Callback used to receive the results of trying to fetch symbols. The string given is the path
  // where the symbols were downloaded. If the string is empty the symbols were unavailable. The
  // error is only set in the event of a connection error. If the symbols are simply unavailable the
  // error will not be set.
  using FetchCallback = fit::callback<void(const Err&, const std::string&)>;

  enum class State {
    kInitializing,  // The server just gets created. It will become kBusy or kReady shortly.
    kAuth,          // The user's credentials have failed authentication.
    kBusy,          // The server is doing authentication.
    kReady,         // The authentication is done and the server is ready to use.
    kUnreachable,   // Too many failed downloads and the server is unusable.
  };

  static std::unique_ptr<SymbolServer> FromURL(Session* session, const std::string& url,
                                               bool require_authentication);

  const std::string& name() const { return name_; }

  const std::vector<std::string>& error_log() const { return error_log_; }

  State state() const { return state_; }
  void set_state_change_callback(fit::callback<void(SymbolServer*, State)> cb) {
    state_change_callback_ = std::move(cb);
  }

  // Attempt to download symbols for the given build ID.
  virtual void Fetch(const std::string& build_id, DebugSymbolFileType file_type,
                     FetchCallback cb) = 0;

  const std::string& access_token() const { return access_token_; }
  void set_access_token(const std::string& access_token) { access_token_ = access_token; }
  const std::string& refresh_token() const { return refresh_token_; }
  void set_refresh_token(const std::string& refresh_token) { refresh_token_ = refresh_token; }

 protected:
  explicit SymbolServer(Session* session, const std::string& name)
      : ClientObject(session), name_(name) {}
  void ChangeState(State state);
  void IncrementRetries();

  // Initialize the class. We want the constructor to do this, but the test mock might need to be
  // manipulated first, so we break this out into a separate function.
  void DoInit();

  // TODO(https://fxbug.dev/42140066): There are currently no use cases where different buckets have
  // different authentication mechanisms (everything is either public, or uses gcloud
  // application-default credentials). This function, and the helpers below, could be shared in the
  // base class (maybe an object?) to authenticate new servers as they are initialized, rather than
  // delegating to the implementations.
  virtual void DoAuthenticate(const std::map<std::string, std::string>& data,
                              fit::callback<void(const Err&)> cb) = 0;

  FILE* GetGoogleApiAuthCache(const char* mode);

  // Load authentication from debugger's config file. Returns whether the loading
  // succeeds.
  bool LoadCachedAuth();

  // Load authentication from gcloud config file. Returns whether the loading succeeds.
  bool LoadGCloudAuth();

  // Use the refresh token to get a new access token.
  void AuthRefresh();

  std::vector<std::string> error_log_;
  size_t retries_ = 0;

  // Incremented each time the state becomes ready.
  size_t ready_count_ = 0;

 private:
  State state_ = State::kInitializing;

  // URL as originally used to construct the class. This is mostly to be used to identify the server
  // in the UI. The actual URL may be processed to handle custom protocol identifiers etc.
  std::string name_;

  std::string access_token_;
  std::string refresh_token_;

  // client_id_ and client_secret_ might be different from kClientId and kClientSecret
  // if we're using gcloud's credential.
  std::string client_id_;
  std::string client_secret_;

  fit::callback<void(SymbolServer*, State)> state_change_callback_;
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_SYMBOL_SERVER_H_
