// Copyright (c) 2012 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/common/prefs.h"

#include <memory>

#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <cros_config/fake_cros_config.h>
#include <gtest/gtest.h>

#include "power_manager/common/cros_config_prefs_source.h"
#include "power_manager/common/file_prefs_store.h"
#include "power_manager/common/prefs_observer.h"
#include "power_manager/common/test_main_loop_runner.h"

namespace {

const int kNumPrefDirectories = 3;
const int64_t kIntTestValue = 0xdeadbeef;
const double kDoubleTestValue = 0.1337;
const char kGarbageString[] = "This is garbage";

const char kIntTestFileName[] = "intfile";
const char kDoubleTestFileName[] = "doublefile";

// The test crashes after this many milliseconds if an expected preference
// change notification is never received.
const int kPrefChangeTimeoutMs = 60 * 1000;

}  // namespace

namespace power_manager {

// Simple class that runs a GLib main loop until it sees a pref get changed.
// Tests should update a pref file and then call RunUntilPrefChanged().
class TestPrefsObserver : public PrefsObserver {
 public:
  explicit TestPrefsObserver(Prefs* prefs) : prefs_(prefs) {
    prefs_->AddObserver(this);
  }
  ~TestPrefsObserver() override { prefs_->RemoveObserver(this); }

  // Runs |loop_| until OnPrefChanged() is called, then quits the loop
  // and returns a string containing the name of the pref that was changed.
  std::string RunUntilPrefChanged() {
    CHECK(loop_runner_.StartLoop(
        base::TimeDelta::FromMilliseconds(kPrefChangeTimeoutMs)))
        << "Pref change not received";
    return pref_name_;
  }

  // PrefsObserver implementation:
  void OnPrefChanged(const std::string& pref_name) override {
    loop_runner_.StopLoop();
    pref_name_ = pref_name;
  }

 private:
  Prefs* prefs_;  // weak; owned by PrefsTest

  TestMainLoopRunner loop_runner_;

  // Name of the last pref that was changed.
  std::string pref_name_;

  DISALLOW_COPY_AND_ASSIGN(TestPrefsObserver);
};

class PrefsTest : public testing::Test {
 public:
  PrefsTest() : test_api_(&prefs_) {}
  ~PrefsTest() override {}

  void SetUp() override {
    paths_.clear();
    // Create new temp directories.
    for (int i = 0; i < kNumPrefDirectories; ++i) {
      temp_dir_generators_[i].reset(new base::ScopedTempDir());
      ASSERT_TRUE(temp_dir_generators_[i]->CreateUniqueTempDir());
      EXPECT_TRUE(temp_dir_generators_[i]->IsValid());
      paths_.push_back(temp_dir_generators_[i]->GetPath());
    }

    // By default, don't defer writes.
    test_api_.set_write_interval(base::TimeDelta());
  }

 protected:
  PrefsSourceInterfaceVector GetSources() {
    PrefsSourceInterfaceVector sources;
    cros_config_ = new brillo::FakeCrosConfig();
    sources.emplace_back(new CrosConfigPrefsSource(
        std::unique_ptr<brillo::CrosConfigInterface>(cros_config_)));
    // The first path will be used for the store; the rest become sources.
    for (int i = 1; i < kNumPrefDirectories; ++i) {
      sources.emplace_back(new FilePrefsStore(paths_[i]));
    }
    return sources;
  }

  void InitPrefs() {
    ASSERT_TRUE(
        prefs_.Init(std::make_unique<FilePrefsStore>(paths_[0]), GetSources()));
  }

  std::vector<base::FilePath> paths_;
  std::unique_ptr<base::ScopedTempDir>
      temp_dir_generators_[kNumPrefDirectories];

  brillo::FakeCrosConfig* cros_config_;  // weak

  Prefs prefs_;
  Prefs::TestApi test_api_;
};

// Test read/write with only one directory.
TEST_F(PrefsTest, TestOneDirectory) {
  ASSERT_TRUE(prefs_.Init(std::make_unique<FilePrefsStore>(paths_[0]),
                          PrefsSourceInterfaceVector()));

  // Make sure the pref files don't already exist.
  EXPECT_FALSE(base::PathExists(paths_[0].Append(kIntTestFileName)));
  EXPECT_FALSE(base::PathExists(paths_[0].Append(kDoubleTestFileName)));

  // Write int and double values to pref files.
  prefs_.SetInt64(kIntTestFileName, kIntTestValue);
  prefs_.SetDouble(kDoubleTestFileName, kDoubleTestValue);

  // Make sure the files were only created in the first directory.
  for (int i = 0; i < kNumPrefDirectories; ++i) {
    if (i == 0) {
      EXPECT_TRUE(base::PathExists(paths_[i].Append(kIntTestFileName)));
      EXPECT_TRUE(base::PathExists(paths_[i].Append(kDoubleTestFileName)));
      continue;
    }
    EXPECT_FALSE(base::PathExists(paths_[i].Append(kIntTestFileName)));
    EXPECT_FALSE(base::PathExists(paths_[i].Append(kDoubleTestFileName)));
  }

  // Now read them back and make sure they have the right values.
  int64_t int_value = -1;
  double double_value = -1;
  EXPECT_TRUE(prefs_.GetInt64(kIntTestFileName, &int_value));
  EXPECT_TRUE(prefs_.GetDouble(kDoubleTestFileName, &double_value));
  EXPECT_EQ(kIntTestValue, int_value);
  EXPECT_EQ(kDoubleTestValue, double_value);
}

// Test read/write with three directories.
TEST_F(PrefsTest, TestThreeDirectories) {
  InitPrefs();

  // Make sure the files don't already exist.
  for (int i = 0; i < kNumPrefDirectories; ++i) {
    EXPECT_FALSE(base::PathExists(paths_[i].Append(kIntTestFileName)));
    EXPECT_FALSE(base::PathExists(paths_[i].Append(kDoubleTestFileName)));
  }

  // Write int and double values to pref files and make sure those files were
  // created in the first directory and not in the other two.
  prefs_.SetInt64(kIntTestFileName, kIntTestValue);
  EXPECT_TRUE(base::PathExists(paths_[0].Append(kIntTestFileName)));
  EXPECT_FALSE(base::PathExists(paths_[1].Append(kIntTestFileName)));
  EXPECT_FALSE(base::PathExists(paths_[2].Append(kIntTestFileName)));

  prefs_.SetDouble(kDoubleTestFileName, kDoubleTestValue);
  EXPECT_TRUE(base::PathExists(paths_[0].Append(kDoubleTestFileName)));
  EXPECT_FALSE(base::PathExists(paths_[1].Append(kDoubleTestFileName)));
  EXPECT_FALSE(base::PathExists(paths_[2].Append(kDoubleTestFileName)));

  // Now read them back and make sure they have the right values.
  int64_t int_value = -1;
  double double_value = -1;
  EXPECT_TRUE(prefs_.GetInt64(kIntTestFileName, &int_value));
  EXPECT_TRUE(prefs_.GetDouble(kDoubleTestFileName, &double_value));
  EXPECT_EQ(kIntTestValue, int_value);
  EXPECT_EQ(kDoubleTestValue, double_value);
}

// Test read from three directories, checking for precedence of directories.
// Prefs in |paths_[i]| take precedence over the same prefs in |paths_[j]|, for
// i < j.
TEST_F(PrefsTest, TestThreeDirectoriesStacked) {
  // Run cycles from 1 to |(1 << kNumPrefDirectories) - 1|.  Each cycle number's
  // bits will represent the paths to populate with pref files.  e.g...
  // cycle 2 = 010b  =>  write prefs to |paths_[1]|
  // cycle 5 = 101b  =>  write prefs to |paths_[0]| and |paths_[2]|
  // cycle 7 = 111b  =>  write prefs to all paths in |paths_|.
  // This will test all the valid combinations of which directories have pref
  // files.
  for (int cycle = 1; cycle < (1 << kNumPrefDirectories); ++cycle) {
    SCOPED_TRACE(
        base::StringPrintf("Testing stacked directories, cycle %d", cycle));
    SetUp();
    Prefs prefs;
    ASSERT_TRUE(
        prefs.Init(std::make_unique<FilePrefsStore>(paths_[0]), GetSources()));

    // Write values to the pref directories as appropriate for this cycle.
    int i;
    for (i = 0; i < kNumPrefDirectories; ++i) {
      const base::FilePath& path = paths_[i];
      // Make sure the files didn't exist already.
      EXPECT_FALSE(base::PathExists(path.Append(kIntTestFileName)));
      EXPECT_FALSE(base::PathExists(path.Append(kDoubleTestFileName)));

      // Determine if this directory path's bit is set in the current cycle
      // number.
      if (!((cycle >> i) & 1))
        continue;

      // For path[i], write the default test values + i.
      // This way, each path's pref file will have a unique value.
      std::string int_string = base::NumberToString(kIntTestValue + i);
      EXPECT_EQ(int_string.size(),
                base::WriteFile(path.Append(kIntTestFileName),
                                int_string.data(), int_string.size()));
      EXPECT_TRUE(base::PathExists(path.Append(kIntTestFileName)));

      std::string double_string = base::NumberToString(kDoubleTestValue + i);
      EXPECT_EQ(double_string.size(),
                base::WriteFile(path.Append(kDoubleTestFileName),
                                double_string.data(), double_string.size()));
      EXPECT_TRUE(base::PathExists(path.Append(kDoubleTestFileName)));
    }

    // Read the pref files.
    int64_t int_value = -1;
    double double_value = -1;
    EXPECT_TRUE(prefs.GetInt64(kIntTestFileName, &int_value));
    EXPECT_TRUE(prefs.GetDouble(kDoubleTestFileName, &double_value));

    // Make sure the earlier paths take precedence over later paths.
    bool is_first_valid_directory = true;
    int num_directories_checked = 0;
    for (i = 0; i < kNumPrefDirectories; ++i) {
      // If the current directory was not used this cycle, disregard it.
      if (!((cycle >> i) & 1))
        continue;
      if (is_first_valid_directory) {
        // First valid directory should match.
        EXPECT_EQ(kIntTestValue + i, int_value);
        EXPECT_EQ(kDoubleTestValue + i, double_value);
        is_first_valid_directory = false;
      } else {
        EXPECT_NE(kIntTestValue + i, int_value);
        EXPECT_NE(kDoubleTestValue + i, double_value);
      }
      ++num_directories_checked;
    }
    EXPECT_GT(num_directories_checked, 0);
  }
}

// Test read from three directories, with the higher precedence directories
// containing garbage.
TEST_F(PrefsTest, TestThreeDirectoriesGarbage) {
  InitPrefs();

  for (int i = 0; i < kNumPrefDirectories; ++i) {
    const base::FilePath& path = paths_[i];
    // Make sure the files didn't exist already.
    EXPECT_FALSE(base::PathExists(path.Append(kIntTestFileName)));
    EXPECT_FALSE(base::PathExists(path.Append(kDoubleTestFileName)));

    // Earlier directories contain garbage.
    // The last one contains valid values.
    std::string int_string;
    std::string double_string;
    if (i < kNumPrefDirectories - 1) {
      int_string = kGarbageString;
      double_string = kGarbageString;
    } else {
      int_string = base::NumberToString(kIntTestValue);
      double_string = base::NumberToString(kDoubleTestValue);
    }
    EXPECT_EQ(int_string.size(),
              base::WriteFile(path.Append(kIntTestFileName), int_string.data(),
                              int_string.size()));
    EXPECT_TRUE(base::PathExists(path.Append(kIntTestFileName)));
    EXPECT_EQ(double_string.size(),
              base::WriteFile(path.Append(kDoubleTestFileName),
                              double_string.data(), double_string.size()));
    EXPECT_TRUE(base::PathExists(path.Append(kDoubleTestFileName)));
  }

  // Read the pref files and make sure the right value was read.
  int64_t int_value = -1;
  double double_value = -1;
  EXPECT_TRUE(prefs_.GetInt64(kIntTestFileName, &int_value));
  EXPECT_TRUE(prefs_.GetDouble(kDoubleTestFileName, &double_value));
  EXPECT_EQ(kIntTestValue, int_value);
  EXPECT_EQ(kDoubleTestValue, double_value);
}

// Make sure that Prefs correctly notifies about changes to pref files.
TEST_F(PrefsTest, WatchPrefs) {
  const char kPrefName[] = "foo";
  const char kPrefValue[] = "1";
  const base::FilePath kFilePath = paths_[0].Append(kPrefName);

  TestPrefsObserver observer(&prefs_);
  InitPrefs();
  EXPECT_EQ(strlen(kPrefValue),
            base::WriteFile(kFilePath, kPrefValue, strlen(kPrefValue)));
  EXPECT_EQ(kPrefName, observer.RunUntilPrefChanged());

  // Write to the file again.
  EXPECT_EQ(strlen(kPrefValue),
            base::WriteFile(kFilePath, kPrefValue, strlen(kPrefValue)));
  EXPECT_EQ(kPrefName, observer.RunUntilPrefChanged());

  // Remove the file.
  EXPECT_TRUE(base::DeleteFile(kFilePath, false));
  EXPECT_EQ(kPrefName, observer.RunUntilPrefChanged());
}

// Test that additional write requests made soon after an initial request
// are deferred.
TEST_F(PrefsTest, DeferredWrites) {
  test_api_.set_write_interval(base::TimeDelta::FromSeconds(120));
  InitPrefs();

  // Write 1 to a pref.
  const char kName[] = "foo";
  prefs_.SetInt64(kName, 1);
  int64_t int64_value = -1;

  // Check that the value was written to disk immediately.
  const base::FilePath kPath = paths_[0].Append(kName);
  std::string file_contents;
  EXPECT_TRUE(base::ReadFileToString(kPath, &file_contents));
  EXPECT_EQ("1", file_contents);
  EXPECT_TRUE(prefs_.GetInt64(kName, &int64_value));
  EXPECT_EQ(1, int64_value);

  // Now write 2 to the pref.  Since the last write happened recently, the
  // file should still contain 1, but GetInt64() should return the new value.
  prefs_.SetInt64(kName, 2);
  file_contents.clear();
  EXPECT_TRUE(base::ReadFileToString(kPath, &file_contents));
  EXPECT_EQ("1", file_contents);
  EXPECT_TRUE(prefs_.GetInt64(kName, &int64_value));
  EXPECT_EQ(2, int64_value);

  // The new value should be written to disk after the timeout fires.
  EXPECT_TRUE(test_api_.TriggerWriteTimeout());
  file_contents.clear();
  EXPECT_TRUE(base::ReadFileToString(kPath, &file_contents));
  EXPECT_EQ("2", file_contents);

  // The timeout should no longer be scheduled.
  EXPECT_FALSE(test_api_.TriggerWriteTimeout());

  // Write 3 and then 4.  Check that the second value is written.
  prefs_.SetInt64(kName, 3);
  prefs_.SetInt64(kName, 4);
  EXPECT_TRUE(test_api_.TriggerWriteTimeout());
  file_contents.clear();
  EXPECT_TRUE(base::ReadFileToString(kPath, &file_contents));
  EXPECT_EQ("4", file_contents);
  EXPECT_TRUE(prefs_.GetInt64(kName, &int64_value));
  EXPECT_EQ(4, int64_value);
  EXPECT_FALSE(test_api_.TriggerWriteTimeout());
}

// Test reads from libcros_config.
TEST_F(PrefsTest, TestLibCrosConfigPrefs) {
  InitPrefs();
  cros_config_->SetString("/power", "power-pref-name", "1");
  cros_config_->SetString("/power", "power_pref_name", "999");  // inaccessible

  int64_t value;
  EXPECT_TRUE(prefs_.GetInt64("power_pref_name", &value));
  EXPECT_EQ(1, value);
  EXPECT_FALSE(prefs_.GetInt64("nonexistent", &value));
}

// Test that CrosConfigPrefsSource::ReadPrefString() trims trailing whitespace.
TEST_F(PrefsTest, TestLibCrosConfigPrefsTrailingWhitespace) {
  InitPrefs();
  cros_config_->SetString("/power", "name", "value \n");

  std::string value;
  EXPECT_TRUE(prefs_.GetString("name", &value));
  EXPECT_EQ("value", value);
}

}  // namespace power_manager
