// 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 <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "base/values.h"
#include "gtest/gtest.h"

#include "thermald/configuration.h"
#include "thermald/config_parser.h"
#include "thermald/thermal_zone.h"

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

namespace thermald {

static const char *kSensor0Name = "sensor 0";
static const int kSensor0ZoneId = 2;
static const int kSensor0SamplingPeriod = 500;

static const char *kSensor1Name = "sensor 1";
static const int kSensor1ChipId = 3;
static const int kSensor1SensorId = 7;
static const int kSensor1SamplingPeriod = 700;

static const char *kFakeDataFile = "/fake/data/file";

static const char *kZone0Name = "zone0";
static const char *kZone1Name = "zone1";

class ConfigParserTest : public testing::Test {
 protected:
  ConfigParserTest() {
    sensors_.reset(new base::ListValue);
    thermal_zones_.reset(new base::ListValue);
    tmp_file_path_.clear();
  }

  virtual ~ConfigParserTest() {
    if (!tmp_file_path_.empty()) {
      DeleteTmpFile();
    }
  }

  void GenerateTmpFile(const string &content) {
    if (!tmp_file_path_.empty()) {
      DeleteTmpFile();
    }

    ASSERT_TRUE(base::CreateTemporaryFile(&tmp_file_path_));

    ASSERT_TRUE(WriteFile(tmp_file_path_, content.c_str(), content.length()));
  }

  void DeleteTmpFile() {
    base::DeleteFile(tmp_file_path_);
    tmp_file_path_.clear();
  }

  bool GenerateAndParseConfigFile() {
    base::DictionaryValue json_cfg;
    json_cfg.SetWithoutPathExpansion("sensors", std::move(sensors_));
    json_cfg.SetWithoutPathExpansion("thermal_zones",
                                     std::move(thermal_zones_));

    string str;
    base::JSONWriter::Write(json_cfg, &str);
    GenerateTmpFile(str);

    cfg_ = ConfigParser::ParseFile(tmp_file_path_);

    return cfg_ != nullptr;
  }

  void AssertSensorExistsAndValuesMatch(const string &sensor_name,
                                        SensorType sensor_type,
                                        int sampling_period) {
    auto it = cfg_->sensors.find(sensor_name);
    ASSERT_NE(cfg_->sensors.end(), it);

    ASSERT_EQ(sensor_name, it->second->name);
    ASSERT_EQ(sensor_type, it->second->type);
    ASSERT_EQ(sampling_period, it->second->sampling_period);
  }

  void AddHwmonSensor(const string &name, int hwmon_chip_id,
                      int hwmon_sensor_id, int sampling_period) {
    auto params = std::make_unique<base::ListValue>();
    params->AppendInteger(hwmon_chip_id);
    params->AppendInteger(hwmon_sensor_id);

    AddSensor(name, "hwmon", std::move(params), sampling_period);
  }

  void AddThermalZoneSensor(const string &name, int zone_id,
                            int sampling_period) {
    auto params = std::make_unique<base::ListValue>();
    params->AppendInteger(zone_id);

    AddSensor(name, "thermal_zone", std::move(params), sampling_period);
  }

  void AddAth10kSensor(const string &name, const string &ath10k_interface,
                       int sampling_period) {
    auto params = std::make_unique<base::ListValue>();
    params->AppendString(ath10k_interface);

    AddSensor(name, "ath10k", std::move(params), sampling_period);
  }

  void AddFakeSensor(const string &name, const string &fake_data_file,
                     int sampling_period) {
    auto params = std::make_unique<base::ListValue>();
    params->AppendString(fake_data_file);

    AddSensor(name, "fake", std::move(params), sampling_period);
  }

  void AddSensor(const string &name, const string &type,
                 unique_ptr<base::ListValue> params, int sampling_period) {
    auto sensor = std::make_unique<base::ListValue>();
    sensor->AppendString(name);
    sensor->AppendString(type);
    sensor->Append(std::move(params));
    sensor->AppendInteger(sampling_period);

    sensors_->Append(std::move(sensor));
  }

  base::Value *CreateThermalState(
      int id,
      const vector<ThermalPointThresholds> &thresholds,
      const map<string, int> &outputs) {
    base::ListValue *state = new base::ListValue;

    state->AppendInteger(id);

    auto threshold_list = std::make_unique<base::ListValue>();
    for (auto &t : thresholds) {
      auto threshold_pair = std::make_unique<base::ListValue>();
      threshold_pair->AppendInteger(t.activation);
      threshold_pair->AppendInteger(t.bottom);
      threshold_list->Append(std::move(threshold_pair));
    }
    state->Append(std::move(threshold_list));

    auto outputs_dict = std::make_unique<base::DictionaryValue>();
    for (auto &it : outputs) {
      outputs_dict->SetWithoutPathExpansion(
          it.first, std::make_unique<base::Value>(it.second));
    }
    state->Append(std::move(outputs_dict));

    return state;
  }

  void AddThermalZone(const string &name,
                      const vector<string> &sensors,
                      const vector<base::Value *> &states) {
    auto zone = std::make_unique<base::ListValue>();
    zone->AppendString(name);

    auto sensor_list = std::make_unique<base::ListValue>();
    for (auto &s : sensors) {
      sensor_list->AppendString(s);
    }
    zone->Append(std::move(sensor_list));

    auto state_list = std::make_unique<base::ListValue>();
    for (auto s : states) {
      state_list->Append(base::WrapUnique(s));
    }
    zone->Append(std::move(state_list));

    thermal_zones_->Append(std::move(zone));
  }

  base::FilePath tmp_file_path_;
  Configuration *cfg_;

  unique_ptr<base::ListValue> sensors_;
  unique_ptr<base::ListValue> thermal_zones_;
};

class ConfigParserThresholdTest : public ConfigParserTest {
 protected:
  void AddExpectedSensorThresholds(const string &sensor_name,
                                   int activation_threshold,
                                   int bottom_threshold) {
    ThermalPointThresholds thresholds;
    thresholds.activation = activation_threshold;
    thresholds.bottom = bottom_threshold;
    expected_thresholds_.insert(make_pair(sensor_name, thresholds));
  }

  void AssertThresholdsMatch(
      const map<string, ThermalPointThresholds> &actual_thresholds) {
    ASSERT_EQ(expected_thresholds_.size(), actual_thresholds.size());

    auto it0 = expected_thresholds_.begin();
    auto it1 = actual_thresholds.begin();

    for (; it0 != expected_thresholds_.end(); it0++, it1++) {
      ASSERT_EQ(it0->first, it1->first);
      ASSERT_EQ(it1->second.activation, it0->second.activation);
      ASSERT_EQ(it1->second.bottom, it0->second.bottom);
    }
  }

  map<string, ThermalPointThresholds> expected_thresholds_;
};

TEST_F(ConfigParserTest, ParseThermalZoneSensor) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);

  ASSERT_TRUE(GenerateAndParseConfigFile());
  AssertSensorExistsAndValuesMatch(kSensor0Name, kThermalZoneSensor,
                                   kSensor0SamplingPeriod);
}

TEST_F(ConfigParserTest, ParseHwmonSensor) {
  AddHwmonSensor(kSensor1Name, kSensor1ChipId, kSensor1SensorId,
                 kSensor1SamplingPeriod);

  ASSERT_TRUE(GenerateAndParseConfigFile());
  AssertSensorExistsAndValuesMatch(kSensor1Name, kHwmonSensor,
                                   kSensor1SamplingPeriod);
}

TEST_F(ConfigParserTest, ParseAth10kSensor) {
  AddAth10kSensor(kSensor1Name, "wifi0", kSensor1SamplingPeriod);

  ASSERT_TRUE(GenerateAndParseConfigFile());
  AssertSensorExistsAndValuesMatch(kSensor1Name, kAth10kSensor,
                                   kSensor1SamplingPeriod);
  auto it = cfg_->sensors.find(kSensor1Name);
  ASSERT_EQ(string("wifi0"),
            it->second->ath10k_sensor.wlan_interface);
}

TEST_F(ConfigParserTest, ParseFakeSensor) {
  AddFakeSensor(kSensor1Name, kFakeDataFile, kSensor1SamplingPeriod);

  ASSERT_TRUE(GenerateAndParseConfigFile());
  AssertSensorExistsAndValuesMatch(kSensor1Name, kFakeSensor,
                                   kSensor1SamplingPeriod);
  auto it = cfg_->sensors.find(kSensor1Name);
  ASSERT_EQ(string(kFakeDataFile),
            it->second->fake_sensor.fake_data_file);
}

TEST_F(ConfigParserTest, ParseMultipleSensors) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddHwmonSensor(kSensor1Name, kSensor1ChipId, kSensor1SensorId,
                 kSensor1SamplingPeriod);

  ASSERT_TRUE(GenerateAndParseConfigFile());
  AssertSensorExistsAndValuesMatch(kSensor0Name, kThermalZoneSensor,
                                   kSensor0SamplingPeriod);
  AssertSensorExistsAndValuesMatch(kSensor1Name, kHwmonSensor,
                                   kSensor1SamplingPeriod);
}

TEST_F(ConfigParserTest, ParseSingleThermalZone) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {})});

  ASSERT_TRUE(GenerateAndParseConfigFile());
  ASSERT_NE(cfg_->zones.end(), cfg_->zones.find(kZone0Name));
}

TEST_F(ConfigParserTest, ParseMultipleThermalZones) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {})});
  AddThermalZone(kZone1Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {})});

  ASSERT_TRUE(GenerateAndParseConfigFile());
  ASSERT_NE(cfg_->zones.end(), cfg_->zones.find(kZone0Name));
  ASSERT_NE(cfg_->zones.end(), cfg_->zones.find(kZone1Name));
}

TEST_F(ConfigParserTest, ThermalStatesAreAddedToZone) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {})});

  ASSERT_TRUE(GenerateAndParseConfigFile());
  const ThermalZoneCfg &zone_cfg(*cfg_->zones[kZone0Name]);
  ASSERT_EQ(2, zone_cfg.states.size());
  ASSERT_EQ(1, zone_cfg.states[0]->id);
  ASSERT_EQ(2, zone_cfg.states[1]->id);
}

TEST_F(ConfigParserTest, OutputsAreAddedToThermalState) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}},
                                     {{"output0", 23}, {"output1", 42}})});

  ASSERT_TRUE(GenerateAndParseConfigFile());

  const ThermalZoneCfg &zone_cfg(*cfg_->zones[kZone0Name]);
  const ThermalStateCfg &state_cfg(*zone_cfg.states[1]);
  ASSERT_EQ(2, state_cfg.outputs.size());
  ASSERT_EQ("output0", state_cfg.outputs[0].key);
  ASSERT_EQ(23, state_cfg.outputs[0].value);
  ASSERT_EQ("output1", state_cfg.outputs[1].key);
  ASSERT_EQ(42, state_cfg.outputs[1].value);
}

TEST_F(ConfigParserThresholdTest,
       SetsWildcardThresholdsForLowestState_SingleSensor) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {})});

  AddExpectedSensorThresholds(kSensor0Name, kTemp0K, kTemp0K);

  ASSERT_TRUE(GenerateAndParseConfigFile());
  AssertThresholdsMatch(cfg_->zones[kZone0Name]->states[0]->thresholds);
}

TEST_F(ConfigParserThresholdTest,
       SetsWildcardThresholdsForLowestState_MultipleSensors) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddHwmonSensor(kSensor1Name, kSensor1ChipId, kSensor1SensorId,
                 kSensor1SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name, kSensor1Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}, {70, 65}}, {})});

  AddExpectedSensorThresholds(kSensor0Name, kTemp0K, kTemp0K);
  AddExpectedSensorThresholds(kSensor1Name, kTemp0K, kTemp0K);

  ASSERT_TRUE(GenerateAndParseConfigFile());
  AssertThresholdsMatch(cfg_->zones[kZone0Name]->states[0]->thresholds);
}

TEST_F(ConfigParserThresholdTest, UseThresholdsFromConfigFile_SingleSensor) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {})});

  AddExpectedSensorThresholds(kSensor0Name, kTemp0K, kTemp0K);

  ASSERT_TRUE(GenerateAndParseConfigFile());
  AssertThresholdsMatch(cfg_->zones[kZone0Name]->states[0]->thresholds);
}

TEST_F(ConfigParserThresholdTest,
       UsesThresholdsFromConfigFile_MultipleSensors) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddHwmonSensor(kSensor1Name, kSensor1ChipId, kSensor1SensorId,
                 kSensor1SamplingPeriod);

  AddThermalZone(kZone0Name, {kSensor0Name, kSensor1Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}, {70, 65}}, {})});

  AddExpectedSensorThresholds(kSensor0Name, 60000, 55000);
  AddExpectedSensorThresholds(kSensor1Name, 70000, 65000);

  ASSERT_TRUE(GenerateAndParseConfigFile());
  AssertThresholdsMatch(cfg_->zones[kZone0Name]->states[1]->thresholds);
}

TEST_F(ConfigParserThresholdTest,
       SetsWildcardValuesForSensorsWithoutThresholds) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{-1, -1}}, {})});

  AddExpectedSensorThresholds(kSensor0Name, kTempInfinite, kTemp0K);

  ASSERT_TRUE(GenerateAndParseConfigFile());
  AssertThresholdsMatch(cfg_->zones[kZone0Name]->states[1]->thresholds);
}

TEST_F(ConfigParserThresholdTest, BottomGreaterThanActivationThreshold) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{55, 55}}, {})});

  ASSERT_FALSE(GenerateAndParseConfigFile());
}

TEST_F(ConfigParserThresholdTest, ActivationAndBottomThresholdsAreEqual) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {}),
                  CreateThermalState(3, {{65, 70}}, {})});

  ASSERT_FALSE(GenerateAndParseConfigFile());
}

TEST_F(ConfigParserThresholdTest, IntermediateStateWithoutThresholds) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {}),
                  CreateThermalState(3, {{-1, -1}}, {}),
                  CreateThermalState(4, {{80, 75}}, {})});

  ASSERT_TRUE(GenerateAndParseConfigFile());
}

/* Verify that the parser rejects non increasing activation thresholds */
TEST_F(ConfigParserThresholdTest, NonIncreasingActivationThresholds) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {}),
                  CreateThermalState(3, {{59, 56}}, {})});

  ASSERT_FALSE(GenerateAndParseConfigFile());
}

/* Verify that the parser rejects non increasing bottom thresholds */
TEST_F(ConfigParserThresholdTest, NonIncreasingBottomThresholds) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {}),
                  CreateThermalState(3, {{71, 54}}, {})});

  ASSERT_FALSE(GenerateAndParseConfigFile());
}

/* Verify that the parser rejects non increasing activation thresholds in a
   configuration with an intermediate state without thresholds */
TEST_F(ConfigParserThresholdTest,
       NonIncreasingActivationThreshold_IntermediateStateWithoutThresholds) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {}),
                  CreateThermalState(3, {{-1, -1}}, {}),
                  CreateThermalState(4, {{59, 56}}, {})});

  ASSERT_FALSE(GenerateAndParseConfigFile());
}

/* Verify that the parser rejects non increasing bottom thresholds in a
   configuration with an intermediate state without thresholds */
TEST_F(ConfigParserThresholdTest,
       NonIncreasingBottomThreshold_IntermediateStateWithoutThresholds) {
  AddThermalZoneSensor(kSensor0Name, kSensor0ZoneId, kSensor0SamplingPeriod);
  AddThermalZone(kZone0Name, {kSensor0Name},
                 {CreateThermalState(1, {}, {}),
                  CreateThermalState(2, {{60, 55}}, {}),
                  CreateThermalState(3, {{-1, -1}}, {}),
                  CreateThermalState(4, {{80, 75}}, {})});

  ASSERT_TRUE(GenerateAndParseConfigFile());
}

}  // namespace thermald
