// Copyright 2018 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_LOGGER_LOGGER_TEST_UTILS_H_
#define COBALT_SRC_LOGGER_LOGGER_TEST_UTILS_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include "src/lib/util/consistent_proto_store.h"
#include "src/lib/util/posix_file_system.h"
#include "src/lib/util/status.h"
#include "src/local_aggregation/local_aggregation.pb.h"
#include "src/logger/fake_logger.h"
#include "src/logger/logger_interface.h"
#include "src/logger/project_context.h"
#include "src/logger/project_context_factory.h"
#include "src/observation_store/observation_store.h"
#include "src/observation_store/observation_store_update_recipient.h"
#include "src/registry/project_configs.h"

namespace cobalt {
namespace logger {
namespace testing {

// A container for information about the set of all locally aggregated reports
// in a registry. This is used by tests to check the output of the
// EventAggregator.
using ExpectedAggregationParams = struct ExpectedAggregationParams {
  // The total number of locally aggregated Observations which should be
  // generated for a single day, assuming that no events have been logged.
  size_t daily_num_obs = 0;
  // The MetricReportIds of the locally aggregated reports in the registry.
  std::set<MetricReportId> metric_report_ids;
  // Keys are the MetricReportIds of all locally aggregated reports in the
  // registry. The value at a key is the number of Observations which should be
  // generated each day for that report, assuming that no events have been
  // logged.
  std::map<MetricReportId, size_t> num_obs_per_report;
  // Keys are the MetricReportIds of all UNIQUE_N_DAY_ACTIVES reports in the
  // registry. The value at a key is the number of event codes for that report's
  // parent MetricDefinition.
  std::map<MetricReportId, size_t> num_event_codes;
  // Keys are the MetricReportIds of all locally aggregated reports in the
  // registry. The value at a key is the set of aggregation windows with units
  // in days for that report.
  std::map<MetricReportId, std::set<uint32_t>> aggregation_days;
};

// A representation of a set of expected UniqueActivesObservations. Used to
// check the values of UniqueActivesObservations generated by the
// EventAggregator.
//
// The outer map is keyed by pairs (MetricReportId, day_index), where the day
// index represents the day index of the expected Observation, and the value at
// a pair is a map keyed by window size. The value of the inner map at a window
// size is a vector of size equal to the number of event codes for the parent
// metric of the report, and the i-th element of the vector is |true| if the
// i-th event code occurred on the device during the specified window, or
// |false| if not.
using ExpectedUniqueActivesObservations =
    std::map<std::pair<MetricReportId, uint32_t>, std::map<uint32_t, std::vector<bool>>>;

// A representation of a set of expected PerDeviceNumericObservations. Used to
// check the values of PerDeviceNumericObservations generated by the
// EventAggregator.
//
// The outer map is keyed by pairs (MetricReportId, day_index), where the day
// index represents the day index of the expected Observation.
//
// The values of the inner map are tuples (component, packed event code, value).
using ExpectedPerDeviceNumericObservations =
    std::map<std::pair<MetricReportId, uint32_t>,
             std::map<uint32_t, std::set<std::tuple<std::string, uint64_t, int64_t>>>>;

// A representation of a set of expected ReportParticipationObservations. Used
// to check the values of ReportParticipationObservations generated by the
// EventAggregator. The first element of each pair is the MetricReportId of a
// report, and the second element represents the day index of an expected
// Observation for that report. a pair is a a set of window sizes.
using ExpectedReportParticipationObservations = std::set<std::pair<MetricReportId, uint32_t>>;

// A mock ObservationStore.
// TODO(zmbush): Move this to a more appropriate location (Perhaps in //src/observation_store)
class FakeObservationStore : public ::cobalt::observation_store::ObservationStoreWriterInterface {
 public:
  using ::cobalt::observation_store::ObservationStoreWriterInterface::StoreObservation;

  StoreStatus StoreObservation(
      std::unique_ptr<::cobalt::observation_store::StoredObservation> message,
      std::unique_ptr<ObservationMetadata> metadata) override {
    messages_received.emplace_back(std::move(message));
    metadata_received.emplace_back(std::move(metadata));
    num_observations_added_++;
    return kOk;
  }

  std::vector<std::unique_ptr<::cobalt::observation_store::StoredObservation>>
      messages_received;                                                // NOLINT
  std::vector<std::unique_ptr<ObservationMetadata>> metadata_received;  // NOLINT

  size_t num_observations_added() { return num_observations_added_; }

  void ResetObservationCounter() { num_observations_added_ = 0; }

 private:
  size_t num_observations_added_ = 0;
};

// A mock ObservationStoreUpdateRecipient.
class TestUpdateRecipient : public ::cobalt::observation_store::ObservationStoreUpdateRecipient {
 public:
  void NotifyObservationsAdded() override { invocation_count++; }

  int invocation_count = 0;
};

// A mock ConsistentProtoStore. Its Read() and Write() methods increment
// counts of their invocations.
class MockConsistentProtoStore : public ::cobalt::util::ConsistentProtoStore {
 public:
  explicit MockConsistentProtoStore(std::string filename)
      : ::cobalt::util::ConsistentProtoStore(std::move(filename), &fs_) {
    read_count_ = 0;
    write_count_ = 0;
  }

  ~MockConsistentProtoStore() override = default;

  // To set the stored proto in a test, use |set_stored_proto| instead of Write.
  ::cobalt::util::Status Write(const google::protobuf::MessageLite& /*proto*/) override {
    write_count_++;
    return ::cobalt::util::Status::OK;
  }

  ::cobalt::util::Status Read(google::protobuf::MessageLite* proto) override {
    if (stored_proto_) {
      proto->Clear();
      proto->CheckTypeAndMergeFrom(*stored_proto_);
    }
    read_count_++;
    return ::cobalt::util::Status::OK;
  }

  void ResetCounts() {
    read_count_ = 0;
    write_count_ = 0;
  }

  int read_count_;   // NOLINT
  int write_count_;  // NOLINT

  void set_stored_proto(std::unique_ptr<google::protobuf::MessageLite> proto) {
    stored_proto_ = std::move(proto);
  }

 private:
  ::cobalt::util::PosixFileSystem fs_;
  std::unique_ptr<google::protobuf::MessageLite> stored_proto_;
};

// Creates and returns a ProjectContextFactory from a serialized, base64-encoded Cobalt
// registry.
std::unique_ptr<ProjectContextFactory> GetTestProjectContextFactory(
    const std::string& registry_base64);

// Creates and returns a ProjectContext from a serialized, base64-encoded Cobalt
// registry.
std::unique_ptr<ProjectContext> GetTestProject(const std::string& registry_base64);

// Returns the ReportAggregationKey associated to a report, given a
// ProjectContext containing the report and the report's MetricReportId.
ReportAggregationKey MakeAggregationKey(const ProjectContext& project_context,
                                        const MetricReportId& metric_report_id);

// Returns the AggregationConfig associated to a report, given a ProjectContext
// containing the report and the report's MetricReportId.
AggregationConfig MakeAggregationConfig(const ProjectContext& project_context,
                                        const MetricReportId& metric_report_id);

// Construct a histogram to log from the indices for buckets, and the counts in that bucket.
HistogramPtr NewHistogram(std::vector<uint32_t> indices, std::vector<uint32_t> counts);

// Construct a custom event to log from the names of dimensions, and the values to log for that
// dimension.
EventValuesPtr NewCustomEvent(std::vector<std::string> dimension_names,
                              std::vector<CustomDimensionValue> values);

// Given an ExpectedAggregationParams struct populated with information about
// the locally aggregated reports in a config, return an
// ExpectedUniqueActivesObservations map initialized with that config's
// MetricReportIds and window sizes and with a specified day index, with all
// activity indicators set to false.
//
// The ExpectedUniqueActivesObservations map generated by
// MakeNullExpectedObservations represents the set of Observations that should
// be generated for |day_index| in the case where no activity has been logged
// for any report and where no backfill is needed.
ExpectedUniqueActivesObservations MakeNullExpectedUniqueActivesObservations(
    const ExpectedAggregationParams& expected_params, uint32_t day_index);

// Given an ExpectedAggregationParams struct |expected_params|, return an
// ExpectedReportParticipationObservations containing a pair
// (|metric_report_id|, |day_index|) for each MetricReportId |metric_report_id|
// in |expected_params|.
ExpectedReportParticipationObservations MakeExpectedReportParticipationObservations(
    const ExpectedAggregationParams& expected_params, uint32_t day_index);

// Populates |observations| with the contents of a FakeObservationStore.
// |observations| should be a vector whose size is equal to the number
// of expected observations. Checks the the ObservationStore contains
// the expected number of Observations and that the report_ids of the
// Observations are equal to |expected_report_ids|. Returns true iff all checks
// pass.
bool FetchObservations(std::vector<Observation>* observations,
                       const std::vector<uint32_t>& expected_report_ids,
                       FakeObservationStore* observation_store,
                       TestUpdateRecipient* update_recipient);

// Populates |observation| with the contents of a FakeObservationStore,
// which is expected to contain a single Observation with a report_id
// of |expected_report_id|. Returns true iff all checks pass.
bool FetchSingleObservation(Observation* observation, uint32_t expected_report_id,
                            FakeObservationStore* observation_store,
                            TestUpdateRecipient* update_recipient);

// Given an ExpectedAggregationParams containing information about the set of
// locally aggregated reports in a config, populates a vector |observations|
// with the contents of a FakeObservationStore and checks that the vector
// contains exactly the number of Observations that the EventAggregator should
// generate for a single day index, for each locally aggregated report in that
// config. Does not assume that the contents of the FakeObservationStore have a
// particular order. The size of |observations| is ignored, and can be 0.
bool FetchAggregatedObservations(std::vector<Observation>* observations,
                                 const ExpectedAggregationParams& expected_params,
                                 FakeObservationStore* observation_store,
                                 TestUpdateRecipient* update_recipient);

// Checks that the contents of a FakeObservationStore is a sequence of
// IntegerEventObservations specified by the various parameters. Returns
// true if all checks pass.
bool CheckNumericEventObservations(const std::vector<uint32_t>& expected_report_ids,
                                   uint32_t expected_event_code,
                                   const std::string& expected_component_name,
                                   int64_t expected_int_value,
                                   FakeObservationStore* observation_store,
                                   TestUpdateRecipient* update_recipient);

// Checks that the Observations contained in a FakeObservationStore are exactly
// the UniqueActivesObservations that should be generated for a single day index
// given a representation of the expected activity indicators for that day, for
// each UniqueActives report, for each aggregation window and event code, for a config
// whose locally aggregated reports are all of type UNIQUE_N_DAY_ACTIVES.
//
// TODO(pesk): Support hourly OnDeviceAggregationWindows.
bool CheckUniqueActivesObservations(const ExpectedUniqueActivesObservations& expected_obs,
                                    FakeObservationStore* observation_store,
                                    TestUpdateRecipient* update_recipient);

// Checks that the Observations contained in a FakeObservationStore are exactly
// the PerDeviceNumericObservations and ReportParticipationObservations that
// should be generated for a single day index given a representation of the
// expected activity indicators for that day, for each PER_DEVICE_NUMERIC_STATS
// report, for each aggregation window and event code, for a config whose locally
// aggregated reports are all of type PER_DEVICE_NUMERIC_STATS.
//
// TODO(pesk): Support hourly OnDeviceAggregationWindows.
bool CheckPerDeviceNumericObservations(
    ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs,
    ExpectedReportParticipationObservations expected_report_participation_obs,
    FakeObservationStore* observation_store, TestUpdateRecipient* update_recipient);

}  // namespace testing
}  // namespace logger
}  // namespace cobalt

#endif  // COBALT_SRC_LOGGER_LOGGER_TEST_UTILS_H_
