// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <unistd.h>

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

#include "base/at_exit.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h"
#include "base/time/time.h"
#include "brillo/flag_helper.h"
#include "brillo/syslog_logging.h"
#include "metrics/metrics_library.h"

#include "thermald/ath10k_temperature_sensor.h"
#include "thermald/config_parser.h"
#include "thermald/configuration.h"
#include "thermald/fake_temperature_sensor.h"
#include "thermald/hwmon_temperature_sensor.h"
#include "thermald/iio_temperature_sensor.h"
#include "thermald/key_value_publisher.h"
#include "thermald/metrics_reporter.h"
#include "thermald/temperature_sensor_interface.h"
#include "thermald/temperature_sensor_monitor.h"
#include "thermald/thermal_output_processor.h"
#include "thermald/thermal_zone.h"
#include "thermald/thermal_zone_controller.h"
#include "thermald/thermal_zone_temperature_sensor.h"

using std::make_pair;
using std::map;
using std::string;
using std::unique_ptr;
using std::vector;

namespace thermald {

static const int kMetricsReportingPeriodInSeconds = 5;

struct ThermaldContext {
  unique_ptr<Configuration> cfg;
  std::vector<std::unique_ptr<TemperatureSensorInterface>> temperature_sensors;
  map<string, unique_ptr<TemperatureMonitorInterface>> temperature_monitors;
  KeyValuePublisher output_publisher;
  std::vector<std::unique_ptr<ThermalZone>> thermal_zones;
  std::vector<std::unique_ptr<ThermalZoneController>> thermal_zone_controllers;
  MetricsLibrary metrics_lib;
  unique_ptr<MetricsReporter> metrics_reporter;
};

static bool CreateTemperatureMonitors(ThermaldContext *context) {
  for (const auto &it : context->cfg->sensors) {
    const SensorCfg &sensor_cfg = *it.second;
    std::unique_ptr<TemperatureSensorInterface> sensor;
    if (sensor_cfg.type == kAth10kSensor) {
      sensor = std::make_unique<Ath10kTemperatureSensor>(
          sensor_cfg.ath10k_sensor.wlan_interface, sensor_cfg.name);
    } else if (sensor_cfg.type == kHwmonSensor) {
      sensor = std::make_unique<HwmonTemperatureSensor>(
          sensor_cfg.hwmon_sensor.chip_id, sensor_cfg.hwmon_sensor.sensor_id,
          sensor_cfg.name);
    } else if (sensor_cfg.type == kThermalZoneSensor) {
      sensor = std::make_unique<ThermalZoneTemperatureSensor>(
          sensor_cfg.thermal_zone_sensor.zone_id, sensor_cfg.name);
    } else if (sensor_cfg.type == kIioSensor) {
      sensor = IioTemperatureSensor::Get(sensor_cfg.name,
          sensor_cfg.iio_sensor.iio_device_name,
          sensor_cfg.iio_sensor.iio_sensor_name);
      if (sensor == NULL) {
        return false;
      }
    } else if (sensor_cfg.type == kFakeSensor) {
      sensor = std::make_unique<FakeTemperatureSensor>(
          base::FilePath(sensor_cfg.fake_sensor.fake_data_file),
          sensor_cfg.name);
    } else {
      LOG(ERROR) << "Unknown sensor type " << sensor_cfg.type;
      return false;
    }

    auto monitor = std::make_unique<TemperatureSensorMonitor>(
        sensor.get(),
        base::TimeDelta::FromMilliseconds(sensor_cfg.sampling_period));

    context->temperature_sensors.push_back(std::move(sensor));

    context->temperature_monitors.insert(
        make_pair(sensor_cfg.name, std::move(monitor)));
  }

  return true;
}

static bool SetupMetricsReporter(ThermaldContext *context) {
  context->metrics_reporter.reset(new MetricsReporter(
      context->cfg->uma_metric_prefix,
      &context->output_publisher, &context->metrics_lib,
      base::TimeDelta::FromSeconds(kMetricsReportingPeriodInSeconds)));

  for (auto &it : context->temperature_monitors) {
    context->metrics_reporter->AddTemperature(it.first, it.second.get());
  }

  return true;
}

static bool CreateThermalZones(ThermaldContext *context) {
  for (const auto &it : context->cfg->zones) {
    const ThermalZoneCfg &zone_cfg = *it.second;

    std::unique_ptr<ThermalZone> zone = std::make_unique<ThermalZone>();
    zone->name = zone_cfg.name;

    // Create states in reverse order, the thermal state engine expects the
    // states to be ordered from higher to lower temperatures/criticality.
    for (auto it2 = zone_cfg.states.rbegin(); it2 != zone_cfg.states.rend();
         it2++) {
      const ThermalStateCfg *state_cfg = it2->get();

      std::unique_ptr<ThermalState> state = std::make_unique<ThermalState>();
      state->id = state_cfg->id;
      state->thresholds = state_cfg->thresholds;
      state->outputs = state_cfg->outputs;

      zone->states.push_back(std::move(state));
    }

    context->thermal_zones.push_back(std::move(zone));
  }

  return true;
}

static bool CreateThermalZoneControllers(ThermaldContext *context) {
  for (auto &zone : context->thermal_zones) {
    vector<TemperatureMonitorInterface *> temperature_monitors;

    const ThermalZoneCfg &zone_cfg = *context->cfg->zones[zone->name];
    for (const string &sensor : zone_cfg.sensors) {
      temperature_monitors.push_back(
          context->temperature_monitors[sensor].get());
    }

    context->thermal_zone_controllers.push_back(
        std::make_unique<ThermalZoneController>(
            zone.get(), &context->output_publisher, temperature_monitors));
  }

  return true;
}

}  // namespace thermald

int main(int argc, char *argv[]) {
  base::AtExitManager exit_manager;

  brillo::FlagHelper::Init(argc, argv, "Thermal daemon");
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderr);

  base::SingleThreadTaskExecutor main_loop;
  base::RunLoop run_loop;
  thermald::ThermaldContext context;

  thermald::ThermalOutputProcessor
      thermal_output_processor(&context.output_publisher);

  base::FilePath config_file("/etc/thermald.cfg");
  if (!base::PathExists(config_file)) {
    LOG(WARNING) << "Configuration file '" << config_file.value()
                 << "' does not exist. Exiting";
    return 0;
  }

  context.cfg.reset(thermald::ConfigParser::ParseFile(config_file));
  if (!context.cfg.get()) {
    return -1;
  }

  if (!thermald::CreateTemperatureMonitors(&context)) {
    return -1;
  }

  if (!thermald::CreateThermalZones(&context)) {
    return -1;
  }

  if (!thermald::CreateThermalZoneControllers(&context)) {
    return -1;
  }

  SetupMetricsReporter(&context);

  for (auto &controller : context.thermal_zone_controllers) {
    controller->Start();
  }

  context.metrics_reporter->Start();

  run_loop.Run();
}
