// 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_LOGGER_LOGGER_TEST_UTILS_H_
#define COBALT_LOGGER_LOGGER_TEST_UTILS_H_

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

#include "./gtest.h"
#include "config/project_configs.h"
#include "encoder/shipping_manager.h"
#include "logger/encoder.h"
#include "logger/local_aggregation.pb.h"
#include "logger/logger_interface.h"
#include "util/consistent_proto_store.h"
#include "util/posix_file_system.h"
#include "util/status.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.
typedef 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 window sizes of that report.
  std::map<MetricReportId, std::set<uint32_t>> window_sizes;
} ExpectedAggregationParams;

// 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.
typedef std::map<std::pair<MetricReportId, uint32_t>,
                 std::map<uint32_t, std::vector<bool>>>
    ExpectedUniqueActivesObservations;

// 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).
typedef std::map<
    std::pair<MetricReportId, uint32_t>,
    std::map<uint32_t, std::set<std::tuple<std::string, uint64_t, int64_t>>>>
    ExpectedPerDeviceNumericObservations;

// 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.
typedef std::set<std::pair<MetricReportId, uint32_t>>
    ExpectedReportParticipationObservations;

// A mock ObservationStore.
class FakeObservationStore
    : public ::cobalt::encoder::ObservationStoreWriterInterface {
 public:
  StoreStatus AddEncryptedObservation(
      std::unique_ptr<EncryptedMessage> 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<EncryptedMessage>> messages_received;
  std::vector<std::unique_ptr<ObservationMetadata>> metadata_received;

  size_t num_observations_added() override { return num_observations_added_; }

  void ResetObservationCounter() override { num_observations_added_ = 0; }

 private:
  size_t num_observations_added_ = 0;
};

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

  int invocation_count = 0;
};

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

  ~MockConsistentProtoStore() {}

  ::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 {
    read_count_++;
    return ::cobalt::util::Status::OK;
  }

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

  int read_count_;
  int write_count_;
};

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

// 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<Observation2>* 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(Observation2* 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<Observation2>* 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 window size and event code, for a config
// whose locally aggregated reports are all of type UNIQUE_N_DAY_ACTIVES.
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 window size and event code, for a config whose locally
// aggregated reports are all of type PER_DEVICE_NUMERIC_STATS.
bool CheckPerDeviceNumericObservations(
    ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs,
    ExpectedReportParticipationObservations expected_report_participation_obs,
    FakeObservationStore* observation_store,
    TestUpdateRecipient* update_recipient);

// An implementation of LoggerInterface that counts how many times the Log*
// methods were called for purposes of testing that internal metrics are being
// collected properly.
class FakeLogger : public LoggerInterface {
 public:
  Status LogEvent(uint32_t metric_id, uint32_t event_code) override {
    call_count_ += 1;
    return Status::kOK;
  }
  Status LogEventCount(uint32_t metric_id,
                       const std::vector<uint32_t>& event_codes,
                       const std::string& component,
                       int64_t period_duration_micros,
                       uint32_t count) override {
    call_count_ += 1;
    return Status::kOK;
  }
  Status LogElapsedTime(uint32_t metric_id,
                        const std::vector<uint32_t>& event_codes,
                        const std::string& component,
                        int64_t elapsed_micros) override {
    call_count_ += 1;
    return Status::kOK;
  }
  Status LogFrameRate(uint32_t metric_id,
                      const std::vector<uint32_t>& event_codes,
                      const std::string& component, float fps) override {
    call_count_ += 1;
    return Status::kOK;
  }
  Status LogMemoryUsage(uint32_t metric_id,
                        const std::vector<uint32_t>& event_codes,
                        const std::string& component, int64_t bytes) override {
    call_count_ += 1;
    return Status::kOK;
  }
  Status LogIntHistogram(uint32_t metric_id,
                         const std::vector<uint32_t>& event_codes,
                         const std::string& component,
                         HistogramPtr histogram) override {
    call_count_ += 1;
    return Status::kOK;
  }
  Status LogString(uint32_t metric_id, const std::string& str) override {
    call_count_ += 1;
    return Status::kOK;
  }
  Status LogCustomEvent(uint32_t metric_id,
                        EventValuesPtr event_values) override {
    call_count_ += 1;
    return Status::kOK;
  }

  uint32_t call_count() { return call_count_; }

 private:
  uint32_t call_count_ = 0;
};

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

#endif  //  COBALT_LOGGER_LOGGER_TEST_UTILS_H_
