// 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;

  // Make SystemDataInterface move-only
  SystemDataInterface(SystemDataInterface const&) = delete;
  SystemDataInterface& operator=(SystemDataInterface const&) = delete;
  explicit SystemDataInterface() = default;

  // Returns the SystemProfile for the current system.
  [[nodiscard]] virtual const SystemProfile& system_profile() 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".
  //
  // |experiment_tokens|: A list of experiment tokens which the shuffler can convert to experiment
  // ids.
  //
  // |experiment_ids|: A list of experiments that are active on the device.
  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,
             const std::vector<ExperimentToken>& experiment_tokens = {},
             const std::vector<int64_t>& experiment_ids = {});

  ~SystemData() override = default;

  // Make SystemData move-only
  SystemData(SystemData const&) = delete;
  SystemData& operator=(SystemData const&) = delete;

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

  // 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_;
  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_
