// 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_CONFIG_H_
#define LIBWEAVE_SRC_CONFIG_H_

#include <set>
#include <string>
#include <vector>

#include <base/callback.h>
#include <base/gtest_prod_util.h>
#include <weave/error.h>
#include <weave/provider/config_store.h>

#include "src/privet/privet_types.h"

namespace weave {

class StorageInterface;

enum class RootClientTokenOwner {
  // Keep order as it's used with order comparison operators.
  kNone,
  kClient,
  kCloud,
};

// Handles reading buffet config and state files.
class Config final {
 public:
  struct Settings : public weave::Settings {
    std::string refresh_token;
    std::string robot_account;
    std::string last_configured_ssid;
    std::vector<uint8_t> secret;
    RootClientTokenOwner root_client_token_owner{RootClientTokenOwner::kNone};
  };

  using OnChangedCallback = base::Callback<void(const weave::Settings&)>;
  ~Config() = default;

  explicit Config(provider::ConfigStore* config_store);

  void AddOnChangedCallback(const OnChangedCallback& callback);
  const Config::Settings& GetSettings() const;

  // Allows editing of config. Makes sure that callbacks were called and changes
  // were saved.
  // User can commit changes by calling Commit method or by destroying the
  // object.
  class Transaction final {
   public:
    explicit Transaction(Config* config)
        : config_(config), settings_(&config->settings_) {
      CHECK(config_);
    }

    ~Transaction();

    void set_client_id(const std::string& id) { settings_->client_id = id; }
    void set_client_secret(const std::string& secret) {
      settings_->client_secret = secret;
    }
    void set_api_key(const std::string& key) { settings_->api_key = key; }
    void set_oauth_url(const std::string& url) { settings_->oauth_url = url; }
    void set_service_url(const std::string& url) {
      settings_->service_url = url;
    }
    void set_name(const std::string& name) { settings_->name = name; }
    void set_description(const std::string& description) {
      settings_->description = description;
    }
    void set_location(const std::string& location) {
      settings_->location = location;
    }
    void set_local_anonymous_access_role(AuthScope role) {
      settings_->local_anonymous_access_role = role;
    }
    void set_local_discovery_enabled(bool enabled) {
      settings_->local_discovery_enabled = enabled;
    }
    void set_local_pairing_enabled(bool enabled) {
      settings_->local_pairing_enabled = enabled;
    }
    void set_cloud_id(const std::string& id) { settings_->cloud_id = id; }
    void set_refresh_token(const std::string& token) {
      settings_->refresh_token = token;
    }
    void set_robot_account(const std::string& account) {
      settings_->robot_account = account;
    }
    void set_last_configured_ssid(const std::string& ssid) {
      settings_->last_configured_ssid = ssid;
    }
    void set_secret(const std::vector<uint8_t>& secret) {
      settings_->secret = secret;
    }
    void set_root_client_token_owner(
        RootClientTokenOwner root_client_token_owner) {
      settings_->root_client_token_owner = root_client_token_owner;
    }

    void Commit();

   private:
    FRIEND_TEST_ALL_PREFIXES(ConfigTest, Setters);
    void set_device_id(const std::string& id) {
      config_->settings_.device_id = id;
    }

    friend class Config;
    void LoadState();
    Config* config_;
    Settings* settings_;
    bool save_{true};
  };

 private:
  void Load();
  void Save();

  Settings settings_;
  provider::ConfigStore* config_store_{nullptr};
  std::vector<OnChangedCallback> on_changed_;

  DISALLOW_COPY_AND_ASSIGN(Config);
};

}  // namespace weave

#endif  // LIBWEAVE_SRC_CONFIG_H_
