// Copyright 2015 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 "thermald/thermal_state_engine.h"

#include <map>
#include <string>
#include <vector>

#include "base/check.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"

#include "thermald/thermal_zone.h"

using std::pair;
using std::string;
using std::vector;

namespace thermald {

static const int kTemperatureUnknown = kTemp0K;

static const ThermalState kInitialState = {
  .id = 0,
};

ThermalStateEngine::ThermalStateEngine(const ThermalZone *zone)
    : zone_(zone), current_state_(&kInitialState) {
  DCHECK(zone);
}

bool ThermalStateEngine::ProcessTemperatureUpdate(const string &thermal_point,
                                                  int temperature) {
  if (!UpdateThermalPointStatus(thermal_point, temperature)) {
    return false;
  }

  const ThermalState *state = DetermineThermalState();
  if (state != current_state_) {
    string temperatures;
    for (auto &it : thermal_point_status_map_) {
      if (!temperatures.empty()) {
        temperatures += ", ";
      }
      temperatures += base::StringPrintf("%s = %d", it.first.c_str(),
                                         it.second.temperature / 1000);
    }

    LOG(INFO) << "[" << zone_->name << "] Thermal state changed from "
              << current_state_->id << " to " << state->id
              << " (" << temperatures << ")";

    current_state_ = state;
    InitNewThermalState();
  }

  return true;
}

ThermalPointStatus *ThermalStateEngine::GetThermalPointStatus(
    const string &thermal_point) {
  auto it = thermal_point_status_map_.find(thermal_point);
  if (it != thermal_point_status_map_.end()) {
    return &it->second;
  }

  ThermalPointStatus thermal_point_status;
  thermal_point_status.temperature = kTemperatureUnknown;
  thermal_point_status.threshold_cleared = true;

  thermal_point_status_map_.insert(
      make_pair(thermal_point, thermal_point_status));
  it = thermal_point_status_map_.find(thermal_point);

  return &it->second;
}

bool ThermalStateEngine::UpdateThermalPointStatus(const string &thermal_point,
                                                  int temperature) {
  ThermalPointStatus *thermal_point_status =
      GetThermalPointStatus(thermal_point);
  thermal_point_status->temperature = temperature;

  if (current_state_ != &kInitialState) {
    ThermalPointThresholds thresholds;
    if (!GetThermalPointThresholds(*current_state_, thermal_point,
                                   &thresholds)) {
      return false;
    }

    if (thermal_point_status->threshold_cleared) {
      if (temperature >= thresholds.activation) {
        thermal_point_status->threshold_cleared = false;
      }
    } else {
      if (temperature <= thresholds.bottom) {
        thermal_point_status->threshold_cleared = true;
      }
    }
  }

  return true;
}

const ThermalState *ThermalStateEngine::DetermineThermalState() {
  for (auto &state : zone_->states) {
    // Find the first state with a surpassed (>=) temperature threshold.
    for (auto &it : thermal_point_status_map_) {
      const auto &thermal_point = it.first;
      const ThermalPointStatus &thermal_point_status = it.second;

      ThermalPointThresholds thresholds;
      if (!GetThermalPointThresholds(*state, thermal_point, &thresholds)) {
        return nullptr;
      }

      if (thermal_point_status.temperature >= thresholds.activation) {
        return state.get();
      }

      if (state.get() == current_state_) {
        if (!thermal_point_status.threshold_cleared &&
            (thermal_point_status.temperature > thresholds.bottom)) {
          // Block transition to a less critical ("cooler") state until the
          // bottom thresholds of all thermal points were reached.
          return current_state_;
        }
      }
    }
  }

  LOG(ERROR) << "[" << zone_->name << "] No applicable thermal state found!!!";

  return nullptr;
}

bool ThermalStateEngine::GetThermalPointThresholds(
    const ThermalState &state, const string &thermal_point,
    ThermalPointThresholds *thresholds) const {
  auto it = state.thresholds.find(thermal_point);
  if (it == state.thresholds.end()) {
    LOG(ERROR) << "[" << zone_->name << "] Thermal state " << state.id
               << " has no thresholds for thermal point '" << thermal_point
               << "'";
    return false;
  }

  *thresholds = it->second;

  return true;
}

void ThermalStateEngine::InitNewThermalState() {
  // Initialize the threshold_cleared flag for each thermal point. The flag is
  // set if the current temperature of the thermal point is below the activation
  // threshold and cleared otherwise.
  for (auto &it : thermal_point_status_map_) {
    ThermalPointThresholds thresholds;
    if (!GetThermalPointThresholds(*current_state_, it.first, &thresholds)) {
      return;
    }

    ThermalPointStatus &thermal_point_status = it.second;
    if (thermal_point_status.temperature >= thresholds.activation) {
      thermal_point_status.threshold_cleared = false;
    } else {
      thermal_point_status.threshold_cleared = true;
    }
  }
}

}  // namespace thermald
