// 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
