// 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_output_processor.h"

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

#include "base/bind.h"
#include "base/callback.h"
#include "base/check.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_split.h"
#include "base/time/time.h"
#include "base/timer/timer.h"

#include "thermald/ath10k_interface.h"
#include "thermald/cpufreq_device.h"
#include "thermald/key_value_publisher.h"

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

namespace thermald {

static const int kDeferredOpsPeriodInSeconds = 10;

ThermalOutputProcessor::ThermalOutputProcessor(KeyValuePublisher *outputs)
    : weak_ptr_factory_(this) {
  DCHECK(outputs);

  if (!CpufreqDevice::GetDevices(&cpufreq_devices_)) {
    LOG(WARNING) << "Failed to get cpufreq devices";
  }

#if BASE_VER < 860220
  subscription_.reset(outputs->Subscribe(base::Bind(
      &ThermalOutputProcessor::OnOutputSet,
      weak_ptr_factory_.GetWeakPtr())).release());
#else
  subscription_ = outputs->Subscribe(base::Bind(
      &ThermalOutputProcessor::OnOutputSet, weak_ptr_factory_.GetWeakPtr()));
#endif
}

ThermalOutputProcessor::Status ThermalOutputProcessor::ProcessValueAth10k(
    const vector<string> &key_parts, int value) {
  if (key_parts.size() != 3) {
    return kInvalidKey;
  }

  if (key_parts[2] != "max_tx_duty_cycle") {
    return kInvalidKey;
  }

  string name_interface(key_parts[1]);
  Ath10kInterface *ath10k_if;
  auto it = ath10k_interfaces_.find(name_interface);
  if (it != ath10k_interfaces_.end()) {
    ath10k_if = it->second.get();
  } else {
    if (!Ath10kInterface::IsAth10kInterface(name_interface)) {
      return kInvalidKey;
    }

    ath10k_if = new Ath10kInterface(name_interface);
    ath10k_interfaces_.insert(
        make_pair(name_interface, unique_ptr<Ath10kInterface>(ath10k_if)));
  }

  if (!ath10k_if->SetMaxTxDutyCycle(value)) {
    // To configure the duty cycle the ath10k interface needs to be enabled and
    // be in AP mode. Assume that the interface hasn't been fully configured yet
    // and try again later.
    return kDeferred;
  }

  return kOk;
}

ThermalOutputProcessor::Status ThermalOutputProcessor::ProcessValueCpu(
    const vector<string> &key_parts, int value) {
  if (key_parts.size() != 2) {
    return kInvalidKey;
  }

  if (key_parts[1] != "max_freq") {
    return kInvalidKey;
  }

  for (auto &cpufreq_dev : cpufreq_devices_) {
    cpufreq_dev->SetMaximumFrequency(value);
  }

  return kOk;
}

ThermalOutputProcessor::Status ThermalOutputProcessor::ProcessOutput(
    const string &key, int value) {
  vector<string> key_parts =
      base::SplitString(key, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  if (key_parts.empty()) {
    LOG(ERROR) << "Invalid key: " << key;
    return kInvalidKey;
  }

  Status status;
  if (key_parts[0] == "ath10k") {
    status = ProcessValueAth10k(key_parts, value);
  } else if(key_parts[0] == "cpu") {
    status = ProcessValueCpu(key_parts, value);
  } else {
    return kSkipped;
  }

  if (status == kInvalidKey) {
    LOG(ERROR) << "Invalid key: " << key;
    return kInvalidKey;
  }

  return status;
}

void ThermalOutputProcessor::OnOutputSet(const string &key, int value) {
  Status status = ProcessOutput(key, value);
  if (status == kOk) {
    // Processing was successful, make sure to remove a potential entry from
    // the list of deferred values.
    deferred_values_.erase(key);

    if (deferred_values_.empty() && deferred_values_timer_.IsRunning()) {
      deferred_values_timer_.Stop();
    }
  } else if (status == kDeferred) {
    // The system could not complete the processing of the value, but later
    // attempts might succeed. Set up deferred processing for this value.
    deferred_values_[key] = value;

    if (!deferred_values_timer_.IsRunning()) {
      deferred_values_timer_.Start(
          FROM_HERE,
          base::TimeDelta::FromSeconds(kDeferredOpsPeriodInSeconds),
          base::Bind(&ThermalOutputProcessor::ProcessDeferredOutputs,
                     weak_ptr_factory_.GetWeakPtr()));
    }
  }
}

void ThermalOutputProcessor::ProcessDeferredOutputs() {
  LOG(INFO) << "Processing deferred outputs";

  auto it = deferred_values_.begin();
  while (it != deferred_values_.end()) {
    Status status = ProcessOutput(it->first, it->second);
    auto it_next = std::next(it);
    if (status == kOk) {
      deferred_values_.erase(it);
    }

    it = it_next;
  }

  if (deferred_values_.empty()) {
    LOG(INFO) << "All deferred outputs processed";
    deferred_values_timer_.Stop();
  }
}

}  // namespace thermald
