// Copyright (c) 2013 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 "power_manager/powerd/policy/ambient_light_handler.h"

#include <cmath>
#include <limits>

#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>

#include "power_manager/powerd/system/ambient_light_sensor_interface.h"

namespace power_manager {
namespace policy {

namespace {

// Number of light sensor responses required to overcome temporal hysteresis.
const int kHysteresisThreshold = 2;

}  // namespace

// static
BacklightBrightnessChange_Cause AmbientLightHandler::ToProtobufCause(
    BrightnessChangeCause als_cause) {
  switch (als_cause) {
    case BrightnessChangeCause::AMBIENT_LIGHT:
      return BacklightBrightnessChange_Cause_AMBIENT_LIGHT_CHANGED;
    case BrightnessChangeCause::EXTERNAL_POWER_CONNECTED:
      return BacklightBrightnessChange_Cause_EXTERNAL_POWER_CONNECTED;
    case BrightnessChangeCause::EXTERNAL_POWER_DISCONNECTED:
      return BacklightBrightnessChange_Cause_EXTERNAL_POWER_DISCONNECTED;
  }
  NOTREACHED() << "Invalid cause " << static_cast<int>(als_cause);
  return BacklightBrightnessChange_Cause_AMBIENT_LIGHT_CHANGED;
}

constexpr size_t AmbientLightHandler::kNumRecentReadingsToLog;

AmbientLightHandler::AmbientLightHandler(
    system::AmbientLightSensorInterface* sensor, Delegate* delegate)
    : sensor_(sensor),
      delegate_(delegate),
      power_source_(PowerSource::AC),
      smoothed_lux_at_last_adjustment_(0),
      smoothed_lux_(0),
      smoothing_constant_(1.0),
      hysteresis_state_(HysteresisState::IMMEDIATE),
      hysteresis_count_(0),
      step_index_(0),
      sent_initial_adjustment_(false) {
  DCHECK(sensor_);
  DCHECK(delegate_);
  recent_lux_readings_.reserve(kNumRecentReadingsToLog);
  sensor_->AddObserver(this);
}

AmbientLightHandler::~AmbientLightHandler() {
  sensor_->RemoveObserver(this);
}

void AmbientLightHandler::Init(const std::string& steps_pref_value,
                               double initial_brightness_percent,
                               double smoothing_constant) {
  std::vector<std::string> lines = base::SplitString(
      steps_pref_value, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  for (std::vector<std::string>::iterator iter = lines.begin();
       iter != lines.end(); ++iter) {
    std::vector<std::string> segments = base::SplitString(
        *iter, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
    BrightnessStep new_step;
    if (segments.size() == 3 &&
        base::StringToDouble(segments[0], &new_step.ac_target_percent) &&
        base::StringToInt(segments[1], &new_step.decrease_lux_threshold) &&
        base::StringToInt(segments[2], &new_step.increase_lux_threshold)) {
      new_step.battery_target_percent = new_step.ac_target_percent;
    } else if (segments.size() == 4 &&
               base::StringToDouble(segments[0], &new_step.ac_target_percent) &&
               base::StringToDouble(segments[1],
                                    &new_step.battery_target_percent) &&
               base::StringToInt(segments[2],
                                 &new_step.decrease_lux_threshold) &&
               base::StringToInt(segments[3],
                                 &new_step.increase_lux_threshold)) {
      // Okay, we've read all the fields.
    } else {
      LOG(FATAL) << "Steps pref has invalid line \"" << *iter << "\"";
    }
    steps_.push_back(new_step);
  }

  // The bottom and top steps should have infinite ranges to ensure that we
  // don't fall off either end.
  CHECK(!steps_.empty()) << "No brightness steps defined in pref";
  CHECK_EQ(steps_.front().decrease_lux_threshold, -1);
  CHECK_EQ(steps_.back().increase_lux_threshold, -1);

  // Start at the step nearest to the initial backlight level.
  double percent_delta = std::numeric_limits<double>::max();
  for (size_t i = 0; i < steps_.size(); i++) {
    double temp_delta =
        fabs(initial_brightness_percent - steps_[i].ac_target_percent);
    if (temp_delta < percent_delta) {
      percent_delta = temp_delta;
      step_index_ = i;
    }
  }
  CHECK_LT(step_index_, steps_.size());

  // Create a synthetic lux value that is in line with |step_index_|.
  // If one or both of the thresholds are unbounded, just do the best we
  // can.
  if (steps_[step_index_].decrease_lux_threshold >= 0 &&
      steps_[step_index_].increase_lux_threshold >= 0) {
    smoothed_lux_at_last_adjustment_ =
        steps_[step_index_].decrease_lux_threshold +
        (steps_[step_index_].increase_lux_threshold -
         steps_[step_index_].decrease_lux_threshold) /
            2;
  } else if (steps_[step_index_].decrease_lux_threshold >= 0) {
    smoothed_lux_at_last_adjustment_ =
        steps_[step_index_].decrease_lux_threshold;
  } else if (steps_[step_index_].increase_lux_threshold >= 0) {
    smoothed_lux_at_last_adjustment_ =
        steps_[step_index_].increase_lux_threshold;
  } else {
    smoothed_lux_at_last_adjustment_ = 0;
  }

  CHECK_GT(smoothing_constant, 0.0);
  CHECK_LE(smoothing_constant, 1.0);
  smoothing_constant_ = smoothing_constant;
}

void AmbientLightHandler::HandlePowerSourceChange(PowerSource source) {
  if (source == power_source_)
    return;

  double old_percent = GetTargetPercent();
  power_source_ = source;
  double new_percent = GetTargetPercent();
  if (new_percent != old_percent && sent_initial_adjustment_) {
    LOG(INFO) << "Going from " << old_percent << "% to " << new_percent
              << "% for power source change (" << name_ << ")";
    delegate_->SetBrightnessPercentForAmbientLight(
        new_percent, source == PowerSource::AC
                         ? BrightnessChangeCause::EXTERNAL_POWER_CONNECTED
                         : BrightnessChangeCause::EXTERNAL_POWER_DISCONNECTED);
  }
}

void AmbientLightHandler::HandleResume() {
  hysteresis_state_ = HysteresisState::RESUMING;
}

std::string AmbientLightHandler::GetRecentReadingsString() const {
  std::string str;
  for (int i = 0; i < recent_lux_readings_.size(); ++i) {
    const int index =
        (recent_lux_start_index_ - i - 1 + recent_lux_readings_.size()) %
        recent_lux_readings_.size();
    str += (i ? " " : "") + std::to_string(recent_lux_readings_[index]);
  }
  return str;
}

void AmbientLightHandler::OnAmbientLightUpdated(
    system::AmbientLightSensorInterface* sensor) {
  DCHECK_EQ(sensor, sensor_);

  // Discard first reading after resume as it is probably cached value.
  if (hysteresis_state_ == HysteresisState::RESUMING) {
    hysteresis_state_ = HysteresisState::IMMEDIATE;
    return;
  }

  const int raw_lux = sensor_->GetAmbientLightLux();
  if (raw_lux < 0) {
    LOG(WARNING) << "Sensor doesn't have valid value";
    return;
  }

  // Currently we notify on every color temperature change.
  if (sensor_->IsColorSensor()) {
    const int color_temperature = sensor_->GetColorTemperature();
    if (color_temperature >= 0)
      delegate_->OnColorTemperatureChanged(color_temperature);
  }

  if (recent_lux_readings_.size() < kNumRecentReadingsToLog) {
    recent_lux_readings_.push_back(raw_lux);
  } else {
    // Overwrite the oldest value with the new reading.
    recent_lux_readings_[recent_lux_start_index_] = raw_lux;
    recent_lux_start_index_ =
        (recent_lux_start_index_ + 1) % recent_lux_readings_.size();
  }

  UpdateSmoothedLux(raw_lux);
  const int new_lux = lround(smoothed_lux_);

  if (hysteresis_state_ != HysteresisState::IMMEDIATE &&
      new_lux == smoothed_lux_at_last_adjustment_) {
    hysteresis_state_ = HysteresisState::STABLE;
    return;
  }

  int new_step_index = step_index_;
  int num_steps = steps_.size();
  if (new_lux > smoothed_lux_at_last_adjustment_) {
    if (hysteresis_state_ != HysteresisState::IMMEDIATE &&
        hysteresis_state_ != HysteresisState::INCREASING) {
      VLOG(1) << "ALS transitioned to brightness increasing (" << name_ << ")";
      hysteresis_state_ = HysteresisState::INCREASING;
      hysteresis_count_ = 0;
    }
    for (; new_step_index < num_steps; new_step_index++) {
      if (new_lux < steps_[new_step_index].increase_lux_threshold ||
          steps_[new_step_index].increase_lux_threshold == -1)
        break;
    }
  } else if (new_lux < smoothed_lux_at_last_adjustment_) {
    if (hysteresis_state_ != HysteresisState::IMMEDIATE &&
        hysteresis_state_ != HysteresisState::DECREASING) {
      VLOG(1) << "ALS transitioned to brightness decreasing (" << name_ << ")";
      hysteresis_state_ = HysteresisState::DECREASING;
      hysteresis_count_ = 0;
    }
    for (; new_step_index >= 0; new_step_index--) {
      if (new_lux > steps_[new_step_index].decrease_lux_threshold ||
          steps_[new_step_index].decrease_lux_threshold == -1)
        break;
    }
  }
  CHECK_GE(new_step_index, 0);
  CHECK_LT(new_step_index, num_steps);

  if (hysteresis_state_ == HysteresisState::IMMEDIATE) {
    step_index_ = new_step_index;
    double target_percent = GetTargetPercent();
    LOG(INFO) << "Immediately going to " << target_percent << "% (step "
              << step_index_ << ") for lux " << new_lux << " (" << name_ << ")";
    smoothed_lux_at_last_adjustment_ = new_lux;
    hysteresis_state_ = HysteresisState::STABLE;
    hysteresis_count_ = 0;
    delegate_->SetBrightnessPercentForAmbientLight(
        target_percent, BrightnessChangeCause::AMBIENT_LIGHT);
    sent_initial_adjustment_ = true;
    return;
  }

  if (static_cast<int>(step_index_) == new_step_index)
    return;

  hysteresis_count_++;
  VLOG(1) << "Incremented hysteresis count to " << hysteresis_count_
          << " (lux went from " << smoothed_lux_at_last_adjustment_ << " to "
          << new_lux << ") (" << name_ << ")";
  if (hysteresis_count_ >= kHysteresisThreshold) {
    step_index_ = new_step_index;
    double target_percent = GetTargetPercent();
    // Log the backlight brightness level that we're suggesting. Note that the
    // delegate may choose to ignore this suggestion for some other reason
    // (system is shutting down, user has manually requested a different level,
    // etc.).
    LOG(INFO) << "Transitioning " << name_ << " to " << target_percent
              << "% (step " << step_index_ << ") for lux " << new_lux << " ["
              << GetRecentReadingsString() << " ...]";
    smoothed_lux_at_last_adjustment_ = new_lux;
    hysteresis_count_ = 1;
    delegate_->SetBrightnessPercentForAmbientLight(
        target_percent, BrightnessChangeCause::AMBIENT_LIGHT);
    sent_initial_adjustment_ = true;
  }
}

double AmbientLightHandler::GetTargetPercent() const {
  CHECK_LT(step_index_, steps_.size());
  return power_source_ == PowerSource::AC
             ? steps_[step_index_].ac_target_percent
             : steps_[step_index_].battery_target_percent;
}

void AmbientLightHandler::UpdateSmoothedLux(int raw_lux) {
  // For the first sensor reading, use raw lux value directly without smoothing.
  if (hysteresis_state_ == HysteresisState::IMMEDIATE) {
    smoothed_lux_ = raw_lux;
  } else {
    smoothed_lux_ = smoothing_constant_ * raw_lux +
                    (1 - smoothing_constant_) * smoothed_lux_;
  }
}

}  // namespace policy
}  // namespace power_manager
