// 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 SRC_LIB_COBALT_CPP_COBALT_LOGGER_IMPL_H_
#define SRC_LIB_COBALT_CPP_COBALT_LOGGER_IMPL_H_

#include <fuchsia/cobalt/cpp/fidl.h>
#include <lib/fidl/cpp/clone.h>
#include <lib/fit/function.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/time.h>

#include <set>

#include "src/lib/backoff/exponential_backoff.h"
#include "src/lib/cobalt/cpp/cobalt_logger.h"

namespace cobalt {

class BaseEvent {
 public:
  BaseEvent() {}
  virtual ~BaseEvent() = default;
  virtual void Log(fuchsia::cobalt::LoggerPtr* logger,
                   fit::function<void(fuchsia::cobalt::Status)> callback) = 0;

  virtual uint32_t metric_id() const { return 0; }
};

class Event : public BaseEvent {
 public:
  Event(uint32_t metric_id) : BaseEvent(), metric_id_(metric_id) {}
  virtual ~Event() = default;
  uint32_t metric_id() const override { return metric_id_; }

 private:
  const uint32_t metric_id_;
};

class OccurrenceEvent : public Event {
 public:
  OccurrenceEvent(uint32_t metric_id, uint32_t event_code)
      : Event(metric_id), event_code_(event_code) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    (*logger)->LogEvent(metric_id(), event_code_, std::move(callback));
  }
  uint32_t event_code() const { return event_code_; }

 private:
  const uint32_t event_code_;
};

class CountEvent : public Event {
 public:
  CountEvent(uint32_t metric_id, uint32_t event_code, const std::string& component,
             int64_t period_duration_micros, int64_t count)
      : Event(metric_id),
        event_code_(event_code),
        component_(component),
        period_duration_micros_(period_duration_micros),
        count_(count) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    (*logger)->LogEventCount(metric_id(), event_code_, component_, period_duration_micros_, count_,
                             std::move(callback));
  }
  uint32_t event_code() const { return event_code_; }
  const std::string& component() const { return component_; }
  int64_t period_duration_micros() const { return period_duration_micros_; }
  int64_t count() const { return count_; }

 private:
  const uint32_t event_code_;
  const std::string component_;
  const int64_t period_duration_micros_;
  const int64_t count_;
};

class ElapsedTimeEvent : public Event {
 public:
  ElapsedTimeEvent(uint32_t metric_id, uint32_t event_code, const std::string& component,
                   int64_t elapsed_micros)
      : Event(metric_id),
        event_code_(event_code),
        component_(component),
        elapsed_micros_(elapsed_micros) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    (*logger)->LogElapsedTime(metric_id(), event_code_, component_, elapsed_micros_,
                              std::move(callback));
  }
  uint32_t event_code() const { return event_code_; }
  const std::string& component() const { return component_; }
  int64_t elapsed_micros() const { return elapsed_micros_; }

 private:
  const uint32_t event_code_;
  const std::string component_;
  const int64_t elapsed_micros_;
};

class FrameRateEvent : public Event {
 public:
  FrameRateEvent(uint32_t metric_id, uint32_t event_code, const std::string& component, float fps)
      : Event(metric_id), event_code_(event_code), component_(component), fps_(fps) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    (*logger)->LogFrameRate(metric_id(), event_code_, component_, fps_, std::move(callback));
  }
  uint32_t event_code() const { return event_code_; }
  const std::string& component() const { return component_; }
  float fps() const { return fps_; }

 private:
  const uint32_t event_code_;
  const std::string component_;
  const float fps_;
};

class MemoryUsageEvent : public Event {
 public:
  MemoryUsageEvent(uint32_t metric_id, uint32_t event_code, const std::string& component,
                   int64_t bytes)
      : Event(metric_id), event_code_(event_code), component_(component), bytes_(bytes) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    (*logger)->LogMemoryUsage(metric_id(), event_code_, component_, bytes_, std::move(callback));
  }
  uint32_t event_code() const { return event_code_; }
  const std::string& component() const { return component_; }
  int64_t bytes() const { return bytes_; }

 private:
  const uint32_t event_code_;
  const std::string component_;
  const int64_t bytes_;
};

class StartTimerEvent : public Event {
 public:
  StartTimerEvent(uint32_t metric_id, uint32_t event_code, const std::string& component,
                  const std::string& timer_id, uint64_t timestamp, uint32_t timeout_s)
      : Event(metric_id),
        event_code_(event_code),
        component_(component),
        timer_id_(timer_id),
        timestamp_(timestamp),
        timeout_s_(timeout_s) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    (*logger)->StartTimer(metric_id(), event_code_, component_, timer_id_, timestamp_, timeout_s_,
                          std::move(callback));
  }
  uint32_t event_code() const { return event_code_; }
  const std::string& component() const { return component_; }
  const std::string& timer_id() const { return timer_id_; }
  uint64_t timestamp() const { return timestamp_; }
  uint32_t timeout_s() const { return timeout_s_; }

 private:
  const uint32_t event_code_;
  const std::string component_;
  const std::string timer_id_;
  const uint64_t timestamp_;
  const uint32_t timeout_s_;
};

class EndTimerEvent : public BaseEvent {
 public:
  EndTimerEvent(const std::string& timer_id, uint64_t timestamp, uint32_t timeout_s)
      : BaseEvent(), timer_id_(timer_id), timestamp_(timestamp), timeout_s_(timeout_s) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    (*logger)->EndTimer(timer_id_, timestamp_, timeout_s_, std::move(callback));
  }
  const std::string& timer_id() const { return timer_id_; }
  uint64_t timestamp() const { return timestamp_; }
  uint32_t timeout_s() const { return timeout_s_; }

 private:
  const std::string timer_id_;
  const uint64_t timestamp_;
  const uint32_t timeout_s_;
};

class IntHistogramEvent : public Event {
 public:
  IntHistogramEvent(uint32_t metric_id, uint32_t event_code, const std::string& component,
                    std::vector<fuchsia::cobalt::HistogramBucket> histogram)
      : Event(metric_id),
        event_code_(event_code),
        component_(component),
        histogram_(std::move(histogram)) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    std::vector<fuchsia::cobalt::HistogramBucket> histogram;
    FX_CHECK(fidl::Clone(histogram_, &histogram) == ZX_OK);
    (*logger)->LogIntHistogram(metric_id(), event_code_, component_, std::move(histogram),
                               std::move(callback));
  }
  uint32_t event_code() const { return event_code_; }
  const std::string& component() const { return component_; }
  const std::vector<fuchsia::cobalt::HistogramBucket>& histogram() const { return histogram_; }

 private:
  const uint32_t event_code_;
  const std::string component_;
  const std::vector<fuchsia::cobalt::HistogramBucket> histogram_;
};

class CustomEvent : public Event {
 public:
  CustomEvent(uint32_t metric_id, std::vector<fuchsia::cobalt::CustomEventValue> event_values)
      : Event(metric_id), event_values_(std::move(event_values)) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    std::vector<fuchsia::cobalt::CustomEventValue> event_values;
    FX_CHECK(fidl::Clone(event_values_, &event_values) == ZX_OK);
    (*logger)->LogCustomEvent(metric_id(), std::move(event_values), std::move(callback));
  }
  const std::vector<fuchsia::cobalt::CustomEventValue>& event_values() const {
    return event_values_;
  }

 private:
  const std::vector<fuchsia::cobalt::CustomEventValue> event_values_;
};

class CobaltEvent : public Event {
 public:
  CobaltEvent(fuchsia::cobalt::CobaltEvent event)
      : Event(event.metric_id), event_(std::move(event)) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    fuchsia::cobalt::CobaltEvent event;
    FX_CHECK(fidl::Clone(event_, &event) == ZX_OK);
    (*logger)->LogCobaltEvent(std::move(event), std::move(callback));
  }

 private:
  const fuchsia::cobalt::CobaltEvent event_;
};

class CobaltEvents : public BaseEvent {
 public:
  CobaltEvents(std::vector<fuchsia::cobalt::CobaltEvent> events)
      : BaseEvent(), events_(std::move(events)) {}
  void Log(fuchsia::cobalt::LoggerPtr* logger,
           fit::function<void(fuchsia::cobalt::Status)> callback) {
    std::vector<fuchsia::cobalt::CobaltEvent> events;
    FX_CHECK(fidl::Clone(events_, &events) == ZX_OK);
    (*logger)->LogCobaltEvents(std::move(events), std::move(callback));
  }

 private:
  const std::vector<fuchsia::cobalt::CobaltEvent> events_;
};

class BaseCobaltLoggerImpl : public CobaltLogger {
 public:
  BaseCobaltLoggerImpl(async_dispatcher_t* dispatcher, uint32_t project_id, size_t max_buffer_size);
  ~BaseCobaltLoggerImpl() override;
  void LogEvent(uint32_t metric_id, uint32_t event_code) override;
  void LogEventCount(uint32_t metric_id, uint32_t event_code, const std::string& component,
                     zx::duration period_duration, int64_t count) override;
  void LogElapsedTime(uint32_t metric_id, uint32_t event_code, const std::string& component,
                      zx::duration elapsed_time) override;
  void LogFrameRate(uint32_t metric_id, uint32_t event_code, const std::string& component,
                    float fps) override;
  void LogMemoryUsage(uint32_t metric_id, uint32_t event_code, const std::string& component,
                      int64_t bytes) override;
  void StartTimer(uint32_t metric_id, uint32_t event_code, const std::string& component,
                  const std::string& timer_id, zx::time timestamp, zx::duration timeout) override;
  void EndTimer(const std::string& timer_id, zx::time timestamp, zx::duration timeout) override;
  void LogIntHistogram(uint32_t metric_id, uint32_t event_code, const std::string& component,
                       std::vector<fuchsia::cobalt::HistogramBucket> histogram) override;
  void LogCustomEvent(uint32_t metric_id,
                      std::vector<fuchsia::cobalt::CustomEventValue> event_values) override;
  virtual void LogCobaltEvent(fuchsia::cobalt::CobaltEvent event) override;
  virtual void LogCobaltEvents(std::vector<fuchsia::cobalt::CobaltEvent> event) override;

 protected:
  void ConnectToCobaltApplication();
  virtual fidl::InterfacePtr<fuchsia::cobalt::LoggerFactory> ConnectToLoggerFactory() = 0;

 private:
  std::function<void(fuchsia::cobalt::Status)> CreateLoggerCallback(const std::string& method_name);
  void OnConnectionError();
  void LogEventOnMainThread(std::unique_ptr<BaseEvent> event);
  void SendEvents();
  void OnTransitFail();
  void LogEventCallback(const BaseEvent* event, fuchsia::cobalt::Status status);
  void LogEvent(std::unique_ptr<BaseEvent> event);

  backoff::ExponentialBackoff backoff_;
  async_dispatcher_t* const dispatcher_;
  fuchsia::cobalt::LoggerFactoryPtr logger_factory_;
  fuchsia::cobalt::LoggerPtr logger_;

  // Because logger_ is bound in the contructor we need to keep track of whether or not the remote
  // server is ready.
  bool logger_ready_ = false;

  // project ID to use when connecting to Cobalt with CreateLoggerFromProjectId().
  const uint32_t project_id_;

  // Maximum combined size of the following buffers.
  const size_t max_buffer_size_;

  std::set<std::unique_ptr<BaseEvent>> events_to_send_;
  std::set<std::unique_ptr<BaseEvent>> events_in_transit_;

  FXL_DISALLOW_COPY_AND_ASSIGN(BaseCobaltLoggerImpl);
};

class CobaltLoggerImpl : public BaseCobaltLoggerImpl {
 public:
  // Use this version of the constructor in order to connect to the Cobalt
  // application via CreateLoggerFromProjectId().
  CobaltLoggerImpl(async_dispatcher_t* dispatcher, std::shared_ptr<sys::ServiceDirectory> services,
                   uint32_t project_id, size_t max_buffer_size);

  ~CobaltLoggerImpl() override{};

 protected:
  virtual fidl::InterfacePtr<fuchsia::cobalt::LoggerFactory> ConnectToLoggerFactory() override;

 private:
  std::shared_ptr<sys::ServiceDirectory> services_;
  FXL_DISALLOW_COPY_AND_ASSIGN(CobaltLoggerImpl);
};

}  // namespace cobalt

#endif  // SRC_LIB_COBALT_CPP_COBALT_LOGGER_IMPL_H_
