// Copyright 2017 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 COBALT_SRC_SYSTEM_DATA_SYSTEM_DATA_H_
#define COBALT_SRC_SYSTEM_DATA_SYSTEM_DATA_H_

#include <memory>
#include <mutex>
#include <string>
#include <utility>
#include <vector>

#include "src/lib/util/protected_fields.h"
#include "src/logger/internal_metrics.h"
#include "src/pb/common.pb.h"
#include "src/pb/observation_batch.pb.h"
#include "src/registry/metric_definition.pb.h"

namespace cobalt::system_data {

struct SoftwareDistributionInfo {
  std::optional<std::string> realm;
  std::optional<std::string> channel;
};

// An abstraction of the interface to SystemData that allows mocking in
// tests.
class SystemDataInterface {
 public:
  virtual ~SystemDataInterface() = default;

  // Returns the SystemProfile for the current system.
  [[nodiscard]] virtual const SystemProfile& system_profile() const = 0;

  // Resets the experiment state to the one provided.
  virtual void SetExperimentState(std::vector<Experiment> experiments) = 0;

  // Returns a vector with all experiments the system has a notion of.
  [[nodiscard]] virtual const std::vector<Experiment>& experiments() const = 0;

  // Resets the current channel value.
  virtual void SetChannel(const std::string& channel) = 0;

  // Resets the current realm value.
  virtual void SetRealm(const std::string& realm) = 0;

  // Resets the current software distribution info.
  virtual void SetSoftwareDistributionInfo(SoftwareDistributionInfo info) = 0;

  // Returns the current channel.
  [[nodiscard]] virtual const std::string& channel() const = 0;

  // Returns the current realm.
  [[nodiscard]] virtual const std::string& realm() const = 0;

  // Returns the current ReleaseStage.
  [[nodiscard]] virtual const ReleaseStage& release_stage() const = 0;

  // Resets the internal metrics to use the provided logger.
  virtual void ResetInternalMetrics(logger::InternalMetrics* internal_metrics) = 0;

  virtual void OnChange(std::function<void()> callback) = 0;
};

// The embedding client creates a singleton instance of SystemData at start-up
// time and uses it to query data about the client's running system. There
// are two categories of data: static data about the system encapsulated in
// the SystemProfile, and dynamic stateful data about the running system.
class SystemData : public SystemDataInterface {
 public:
  // Constructor: Uses the real SystemProfile of the actual running system.
  //
  // |product_name|: The value to use for the |product_name| field of the
  // embedded SystemProfile.
  //
  // |board_name_suggestion|: A suggestion for the value to use for the
  // |board_name| field of the embedded SystemProfile. This may be ignored if
  // SystemData is able to determine the boardh name directly. A value of ""
  // indicates that the caller has no information about board name, so one
  // should be guessed.
  //
  // |release_stage|: The ReleaseStage of the running system.
  //
  // |build_type|: The BuildType of the running system.
  //
  // |version|: The version of the running system. The use of this field is
  // system-specific. For example on Fuchsia a possible value for |version| is
  // "20190220_01_RC00".
  SystemData(const std::string& product_name, const std::string& board_name_suggestion,
             ReleaseStage release_stage, const std::string& version = "",
             SystemProfile::BuildType build_type = SystemProfile::UNKNOWN_TYPE);

  ~SystemData() override = default;

  // Returns a vector with all experiments the system has a notion of.
  const std::vector<Experiment>& experiments() const override {
    auto unprotected_experiments = protected_experiments_.const_lock();
    return unprotected_experiments->experiments;
  }

  // Returns the SystemProfile for the current system.
  const SystemProfile& system_profile() const override { return system_profile_; }

  // Resets the experiment state to the one provided.
  void SetExperimentState(std::vector<Experiment> experiments) override {
    auto unprotected_experiments = protected_experiments_.lock();
    unprotected_experiments->experiments = std::move(experiments);
  }

  // Resets the current channel value.
  void SetChannel(const std::string& channel) override;

  const std::string& channel() const override { return system_profile_.channel(); }

  // Resets the current realm value.
  void SetRealm(const std::string& realm) override;

  const std::string& realm() const override { return system_profile_.realm(); }

  void SetSoftwareDistributionInfo(SoftwareDistributionInfo info) override;

  const ReleaseStage& release_stage() const override { return release_stage_; }

  void ResetInternalMetrics(logger::InternalMetrics* internal_metrics) override;

  void OnChange(std::function<void()> callback) override;

  // Overrides the stored SystemProfile. Useful for testing.
  void OverrideSystemProfile(const SystemProfile& profile);

 private:
  void PopulateSystemProfile();
  void NotifyChange();

  SystemProfile system_profile_;
  logger::InternalMetricsPtr internal_metrics_;
  struct UnprotectedExperiments {
    std::vector<Experiment> experiments;
  };
  util::RWProtectedFields<UnprotectedExperiments> protected_experiments_;
  ReleaseStage release_stage_;
  std::vector<std::function<void()>> change_callbacks_;
};

}  // namespace cobalt::system_data

namespace cobalt::encoder {

using system_data::SystemData;
using system_data::SystemDataInterface;

}  // namespace cobalt::encoder

#endif  // COBALT_SRC_SYSTEM_DATA_SYSTEM_DATA_H_
