// Copyright 2020 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/system/ambient_light_sensor_delegate_file.h"

#include <memory>
#include <utility>

#include <base/compiler_specific.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/file_utils.h>
#include <gtest/gtest.h>

#include "power_manager/common/test_main_loop_runner.h"
#include "power_manager/powerd/system/ambient_light_observer.h"

namespace power_manager {
namespace system {

namespace {

// Abort if it an expected brightness change hasn't been received after this
// many milliseconds.
const int kUpdateTimeoutMs = 5000;

// Frequency with which the ambient light sensor file is polled.
const int kPollIntervalMs = 100;

// Simple AmbientLightObserver implementation that runs the event loop
// until it receives notification that the ambient light level has changed.
class TestObserver : public AmbientLightObserver {
 public:
  TestObserver() {}
  TestObserver(const TestObserver&) = delete;
  TestObserver& operator=(const TestObserver&) = delete;
  ~TestObserver() override {}

  // Runs |loop_| until OnAmbientLightUpdated() is called.
  bool RunUntilAmbientLightUpdated() {
    return loop_runner_.StartLoop(
        base::TimeDelta::FromMilliseconds(kUpdateTimeoutMs));
  }

  // AmbientLightObserver implementation:
  void OnAmbientLightUpdated(AmbientLightSensorInterface* sensor) override {
    loop_runner_.StopLoop();
  }

 private:
  TestMainLoopRunner loop_runner_;
};

}  // namespace

class AmbientLightSensorDelegateFileTest : public ::testing::Test {
 public:
  AmbientLightSensorDelegateFileTest() {}
  AmbientLightSensorDelegateFileTest(
      const AmbientLightSensorDelegateFileTest&) = delete;
  AmbientLightSensorDelegateFileTest& operator=(
      const AmbientLightSensorDelegateFileTest&) = delete;
  ~AmbientLightSensorDelegateFileTest() override {}

 protected:
  void SetUp() override {
    CHECK(temp_dir_.CreateUniqueTempDir());
    device_dir_ = temp_dir_.GetPath().Append("device0");
    CHECK(base::CreateDirectory(device_dir_));
    data_file_ = device_dir_.Append("in_illuminance_input");

    sensor_ = std::make_unique<system::AmbientLightSensor>();
    sensor_->AddObserver(&observer_);
  }

  void TearDown() override { sensor_->RemoveObserver(&observer_); }

  void CreateSensor(SensorLocation location, bool allow_ambient_eq) {
    auto als = std::make_unique<system::AmbientLightSensorDelegateFile>(
        location, allow_ambient_eq);
    als_ = als.get();
    sensor_->SetDelegate(std::move(als));
    als_->set_device_list_path_for_testing(temp_dir_.GetPath());
    als_->set_poll_interval_ms_for_testing(kPollIntervalMs);
    als_->Init(false /* read_immediately */);
  }

  // Writes |lux| to |data_file_| to simulate the ambient light sensor reporting
  // a new light level.
  void WriteLux(int lux) {
    std::string lux_string = base::NumberToString(lux);
    CHECK(brillo::WriteStringToFile(data_file_, lux_string));
  }

  // Temporary directory mimicking a /sys directory containing a set of sensor
  // devices.
  base::ScopedTempDir temp_dir_;

  base::FilePath device_dir_;

  // Illuminance file containing the sensor's current brightness level.
  base::FilePath data_file_;

  TestObserver observer_;

  std::unique_ptr<AmbientLightSensor> sensor_;
  AmbientLightSensorDelegateFile* als_;
};

TEST_F(AmbientLightSensorDelegateFileTest, Basic) {
  CreateSensor(SensorLocation::UNKNOWN, false);

  WriteLux(100);
  ASSERT_TRUE(observer_.RunUntilAmbientLightUpdated());
  EXPECT_EQ(100, sensor_->GetAmbientLightLux());

  WriteLux(200);
  ASSERT_TRUE(observer_.RunUntilAmbientLightUpdated());
  EXPECT_EQ(200, sensor_->GetAmbientLightLux());

  // When the lux value doesn't change, we should still be called.
  WriteLux(200);
  ASSERT_TRUE(observer_.RunUntilAmbientLightUpdated());
  EXPECT_EQ(200, sensor_->GetAmbientLightLux());
}

TEST_F(AmbientLightSensorDelegateFileTest, GiveUpAfterTooManyFailures) {
  CreateSensor(SensorLocation::UNKNOWN, false);

  // Test that the timer is eventually stopped after many failures.
  base::DeleteFile(data_file_);
  for (int i = 0;
       i < AmbientLightSensorDelegateFile::kNumInitAttemptsBeforeGivingUp;
       ++i) {
    EXPECT_TRUE(als_->TriggerPollTimerForTesting());
    EXPECT_LT(sensor_->GetAmbientLightLux(), 0);
  }

  EXPECT_FALSE(als_->TriggerPollTimerForTesting());
  EXPECT_LT(sensor_->GetAmbientLightLux(), 0);
}

TEST_F(AmbientLightSensorDelegateFileTest, FailToFindSensorAtLid) {
  // Test that the timer is eventually stopped after many failures if |sensor_|
  // is unable to find the sensor at the expected location.
  CreateSensor(SensorLocation::LID, false);

  for (int i = 0;
       i < AmbientLightSensorDelegateFile::kNumInitAttemptsBeforeGivingUp;
       ++i) {
    EXPECT_TRUE(als_->TriggerPollTimerForTesting());
    EXPECT_LT(sensor_->GetAmbientLightLux(), 0);
  }

  EXPECT_FALSE(als_->TriggerPollTimerForTesting());
  EXPECT_LT(sensor_->GetAmbientLightLux(), 0);
}

TEST_F(AmbientLightSensorDelegateFileTest, FindSensorAtBase) {
  // Test that |sensor_| is able to find the correct sensor at the expected
  // location.
  base::FilePath loc_file = device_dir_.Append("location");
  CHECK(brillo::WriteStringToFile(loc_file, "base"));

  CreateSensor(SensorLocation::BASE, false);

  WriteLux(100);
  ASSERT_TRUE(observer_.RunUntilAmbientLightUpdated());
  EXPECT_EQ(100, sensor_->GetAmbientLightLux());
}

TEST_F(AmbientLightSensorDelegateFileTest, IsColorSensor) {
  CreateSensor(SensorLocation::UNKNOWN, false);

  // Default sensor does not have color support.
  WriteLux(100);
  ASSERT_TRUE(observer_.RunUntilAmbientLightUpdated());
  EXPECT_FALSE(sensor_->IsColorSensor());

  // Add one color channel.
  base::FilePath color_file = device_dir_.Append("in_illuminance_red_raw");
  CHECK(brillo::WriteStringToFile(color_file, "50"));

  CreateSensor(SensorLocation::UNKNOWN, false);

  WriteLux(100);
  ASSERT_TRUE(observer_.RunUntilAmbientLightUpdated());
  // The sensor should still not have color support -- it needs all 3.
  EXPECT_FALSE(sensor_->IsColorSensor());

  // Add the other two channels.
  color_file = device_dir_.Append("in_illuminance_green_raw");
  CHECK(brillo::WriteStringToFile(color_file, "50"));
  color_file = device_dir_.Append("in_illuminance_blue_raw");
  CHECK(brillo::WriteStringToFile(color_file, "50"));

  CreateSensor(SensorLocation::UNKNOWN, true);

  WriteLux(100);
  ASSERT_TRUE(observer_.RunUntilAmbientLightUpdated());
  // Now we have all channels. The sensor should support color.
  EXPECT_TRUE(sensor_->IsColorSensor());
}

}  // namespace system
}  // namespace power_manager
