// 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_FAKE_LOGGER_H_
#define COBALT_SRC_LOGGER_FAKE_LOGGER_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/logger_interface.h"
#include "src/logger/project_context.h"
#include "src/registry/project_configs.h"

namespace cobalt::logger::testing {

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

  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;

  Status LogElapsedTime(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                        const std::string& component, int64_t elapsed_micros) override;

  Status LogFrameRate(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                      const std::string& component, float fps) override;

  Status LogMemoryUsage(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                        const std::string& component, int64_t bytes) override;

  Status LogIntHistogram(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                         const std::string& component, HistogramPtr histogram) override;

  Status LogOccurrence(uint32_t metric_id, uint64_t count,
                       const std::vector<uint32_t>& event_codes) override;

  Status LogInteger(uint32_t metric_id, int64_t value,
                    const std::vector<uint32_t>& event_codes) override;

  Status LogIntegerHistogram(uint32_t metric_id, HistogramPtr histogram,
                             const std::vector<uint32_t>& event_codes) override;

  Status LogString(uint32_t metric_id, const std::string& string_value,
                   const std::vector<uint32_t>& event_codes) override;

  Status LogCustomEvent(uint32_t metric_id, EventValuesPtr event_values) override;

  Status LogSerializedCustomEvent(uint32_t metric_id,
                                  std::unique_ptr<std::string> serialized_proto) override;

  void RecordLoggerCall(PerProjectLoggerCallsMadeMetricDimensionLoggerMethod method) override {
    if (!internal_logging_paused_) {
      internal_logger_calls_[method]++;
    }
  }

  void PauseInternalLogging() override { internal_logging_paused_ = true; }

  void ResumeInternalLogging() override { internal_logging_paused_ = false; }

  void TrackEvent(Event e) {
    events_logged_.push_back(e);
    last_event_logged_ = std::move(e);
  }
  uint32_t call_count() const { return call_count_; }
  Event last_event_logged() const { return last_event_logged_; }
  Event nth_event_logged(int64_t n) const { return events_logged_[n]; }
  std::map<PerProjectLoggerCallsMadeMetricDimensionLoggerMethod, uint32_t> internal_logger_calls() {
    return internal_logger_calls_;
  }

 private:
  Event last_event_logged_;
  std::vector<Event> events_logged_;
  uint32_t call_count_ = 0;
  std::map<PerProjectLoggerCallsMadeMetricDimensionLoggerMethod, uint32_t> internal_logger_calls_;
  bool internal_logging_paused_ = false;
};

}  // namespace cobalt::logger::testing

#endif  //  COBALT_SRC_LOGGER_FAKE_LOGGER_H_
