//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/common/prefs.h"

#include <inttypes.h>

#include <limits>
#include <string>

#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/macros.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

using std::string;
using testing::_;
using testing::ElementsAre;
using testing::Eq;

namespace {
// Test key used along the tests.
const char kKey[] = "test-key";
}  // namespace

namespace chromeos_update_engine {

class PrefsTest : public ::testing::Test {
 protected:
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    prefs_dir_ = temp_dir_.GetPath();
    ASSERT_TRUE(prefs_.Init(prefs_dir_));
  }

  bool SetValue(const string& key, const string& value) {
    return base::WriteFile(prefs_dir_.Append(key),
                           value.data(),
                           value.length()) == static_cast<int>(value.length());
  }

  base::ScopedTempDir temp_dir_;
  base::FilePath prefs_dir_;
  Prefs prefs_;
};

TEST(Prefs, Init) {
  Prefs prefs;
  const string ns1 = "ns1";
  const string ns2A = "ns2A";
  const string ns2B = "ns2B";
  const string sub_pref = "sp";

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  auto ns1_path = temp_dir.GetPath().Append(ns1);
  auto ns2A_path = ns1_path.Append(ns2A);
  auto ns2B_path = ns1_path.Append(ns2B);
  auto sub_pref_path = ns2A_path.Append(sub_pref);

  EXPECT_TRUE(base::CreateDirectory(ns2B_path));
  EXPECT_TRUE(base::PathExists(ns2B_path));

  EXPECT_TRUE(base::CreateDirectory(sub_pref_path));
  EXPECT_TRUE(base::PathExists(sub_pref_path));

  EXPECT_TRUE(base::PathExists(ns1_path));
  ASSERT_TRUE(prefs.Init(temp_dir.GetPath()));
  EXPECT_FALSE(base::PathExists(ns1_path));
}

TEST_F(PrefsTest, GetFileNameForKey) {
  const char kAllvalidCharsKey[] =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-";
  base::FilePath path;
  EXPECT_TRUE(prefs_.file_storage_.GetFileNameForKey(kAllvalidCharsKey, &path));
  EXPECT_EQ(prefs_dir_.Append(kAllvalidCharsKey).value(), path.value());
}

TEST_F(PrefsTest, GetFileNameForKeyBadCharacter) {
  base::FilePath path;
  EXPECT_FALSE(prefs_.file_storage_.GetFileNameForKey("ABC abc", &path));
}

TEST_F(PrefsTest, GetFileNameForKeyEmpty) {
  base::FilePath path;
  EXPECT_FALSE(prefs_.file_storage_.GetFileNameForKey("", &path));
}

TEST_F(PrefsTest, CreateSubKey) {
  const string name_space = "ns";
  const string sub_pref1 = "sp1";
  const string sub_pref2 = "sp2";
  const string sub_key = "sk";

  EXPECT_EQ(PrefsInterface::CreateSubKey({name_space, sub_pref1, sub_key}),
            "ns/sp1/sk");
  EXPECT_EQ(PrefsInterface::CreateSubKey({name_space, sub_pref2, sub_key}),
            "ns/sp2/sk");
}

TEST_F(PrefsTest, GetString) {
  const string test_data = "test data";
  ASSERT_TRUE(SetValue(kKey, test_data));
  string value;
  EXPECT_TRUE(prefs_.GetString(kKey, &value));
  EXPECT_EQ(test_data, value);
}

TEST_F(PrefsTest, GetStringBadKey) {
  string value;
  EXPECT_FALSE(prefs_.GetString(",bad", &value));
}

TEST_F(PrefsTest, GetStringNonExistentKey) {
  string value;
  EXPECT_FALSE(prefs_.GetString("non-existent-key", &value));
}

TEST_F(PrefsTest, SetString) {
  const char kValue[] = "some test value\non 2 lines";
  EXPECT_TRUE(prefs_.SetString(kKey, kValue));
  string value;
  EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
  EXPECT_EQ(kValue, value);
}

TEST_F(PrefsTest, SetStringBadKey) {
  const char kKeyWithDots[] = ".no-dots";
  EXPECT_FALSE(prefs_.SetString(kKeyWithDots, "some value"));
  EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithDots)));
}

TEST_F(PrefsTest, SetStringCreateDir) {
  const char kValue[] = "test value";
  base::FilePath subdir = prefs_dir_.Append("subdir1").Append("subdir2");
  EXPECT_TRUE(prefs_.Init(subdir));
  EXPECT_TRUE(prefs_.SetString(kKey, kValue));
  string value;
  EXPECT_TRUE(base::ReadFileToString(subdir.Append(kKey), &value));
  EXPECT_EQ(kValue, value);
}

TEST_F(PrefsTest, SetStringDirCreationFailure) {
  EXPECT_TRUE(prefs_.Init(base::FilePath("/dev/null")));
  EXPECT_FALSE(prefs_.SetString(kKey, "test value"));
}

TEST_F(PrefsTest, SetStringFileCreationFailure) {
  base::CreateDirectory(prefs_dir_.Append(kKey));
  EXPECT_FALSE(prefs_.SetString(kKey, "test value"));
  EXPECT_TRUE(base::DirectoryExists(prefs_dir_.Append(kKey)));
}

TEST_F(PrefsTest, GetInt64) {
  ASSERT_TRUE(SetValue(kKey, " \n 25 \t "));
  int64_t value;
  EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
  EXPECT_EQ(25, value);
}

TEST_F(PrefsTest, GetInt64BadValue) {
  ASSERT_TRUE(SetValue(kKey, "30a"));
  int64_t value;
  EXPECT_FALSE(prefs_.GetInt64(kKey, &value));
}

TEST_F(PrefsTest, GetInt64Max) {
  ASSERT_TRUE(SetValue(
      kKey,
      base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::max())));
  int64_t value;
  EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
  EXPECT_EQ(std::numeric_limits<int64_t>::max(), value);
}

TEST_F(PrefsTest, GetInt64Min) {
  ASSERT_TRUE(SetValue(
      kKey,
      base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::min())));
  int64_t value;
  EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
  EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
}

TEST_F(PrefsTest, GetInt64Negative) {
  ASSERT_TRUE(SetValue(kKey, " \t -100 \n "));
  int64_t value;
  EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
  EXPECT_EQ(-100, value);
}

TEST_F(PrefsTest, GetInt64NonExistentKey) {
  int64_t value;
  EXPECT_FALSE(prefs_.GetInt64("random-key", &value));
}

TEST_F(PrefsTest, SetInt64) {
  EXPECT_TRUE(prefs_.SetInt64(kKey, -123));
  string value;
  EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
  EXPECT_EQ("-123", value);
}

TEST_F(PrefsTest, SetInt64BadKey) {
  const char kKeyWithSpaces[] = "s p a c e s";
  EXPECT_FALSE(prefs_.SetInt64(kKeyWithSpaces, 20));
  EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithSpaces)));
}

TEST_F(PrefsTest, SetInt64Max) {
  EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::max()));
  string value;
  EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
  EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::max()),
            value);
}

TEST_F(PrefsTest, SetInt64Min) {
  EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::min()));
  string value;
  EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
  EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::min()),
            value);
}

TEST_F(PrefsTest, GetBooleanFalse) {
  ASSERT_TRUE(SetValue(kKey, " \n false \t "));
  bool value;
  EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
  EXPECT_FALSE(value);
}

TEST_F(PrefsTest, GetBooleanTrue) {
  const char kKey[] = "test-key";
  ASSERT_TRUE(SetValue(kKey, " \t true \n "));
  bool value;
  EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
  EXPECT_TRUE(value);
}

TEST_F(PrefsTest, GetBooleanBadValue) {
  const char kKey[] = "test-key";
  ASSERT_TRUE(SetValue(kKey, "1"));
  bool value;
  EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
}

TEST_F(PrefsTest, GetBooleanBadEmptyValue) {
  const char kKey[] = "test-key";
  ASSERT_TRUE(SetValue(kKey, ""));
  bool value;
  EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
}

TEST_F(PrefsTest, GetBooleanNonExistentKey) {
  bool value;
  EXPECT_FALSE(prefs_.GetBoolean("random-key", &value));
}

TEST_F(PrefsTest, SetBooleanTrue) {
  const char kKey[] = "test-bool";
  EXPECT_TRUE(prefs_.SetBoolean(kKey, true));
  string value;
  EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
  EXPECT_EQ("true", value);
}

TEST_F(PrefsTest, SetBooleanFalse) {
  const char kKey[] = "test-bool";
  EXPECT_TRUE(prefs_.SetBoolean(kKey, false));
  string value;
  EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
  EXPECT_EQ("false", value);
}

TEST_F(PrefsTest, SetBooleanBadKey) {
  const char kKey[] = "s p a c e s";
  EXPECT_FALSE(prefs_.SetBoolean(kKey, true));
  EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKey)));
}

TEST_F(PrefsTest, ExistsWorks) {
  // test that the key doesn't exist before we set it.
  EXPECT_FALSE(prefs_.Exists(kKey));

  // test that the key exists after we set it.
  ASSERT_TRUE(prefs_.SetInt64(kKey, 8));
  EXPECT_TRUE(prefs_.Exists(kKey));
}

TEST_F(PrefsTest, DeleteWorks) {
  // test that it's alright to delete a non-existent key.
  EXPECT_TRUE(prefs_.Delete(kKey));

  // delete the key after we set it.
  ASSERT_TRUE(prefs_.SetInt64(kKey, 0));
  EXPECT_TRUE(prefs_.Delete(kKey));

  // make sure it doesn't exist anymore.
  EXPECT_FALSE(prefs_.Exists(kKey));
}

TEST_F(PrefsTest, SetDeleteSubKey) {
  const string name_space = "ns";
  const string sub_pref = "sp";
  const string sub_key1 = "sk1";
  const string sub_key2 = "sk2";
  auto key1 = prefs_.CreateSubKey({name_space, sub_pref, sub_key1});
  auto key2 = prefs_.CreateSubKey({name_space, sub_pref, sub_key2});
  base::FilePath sub_pref_path = prefs_dir_.Append(name_space).Append(sub_pref);

  ASSERT_TRUE(prefs_.SetInt64(key1, 0));
  ASSERT_TRUE(prefs_.SetInt64(key2, 0));
  EXPECT_TRUE(base::PathExists(sub_pref_path.Append(sub_key1)));
  EXPECT_TRUE(base::PathExists(sub_pref_path.Append(sub_key2)));

  ASSERT_TRUE(prefs_.Delete(key1));
  EXPECT_FALSE(base::PathExists(sub_pref_path.Append(sub_key1)));
  EXPECT_TRUE(base::PathExists(sub_pref_path.Append(sub_key2)));
  ASSERT_TRUE(prefs_.Delete(key2));
  EXPECT_FALSE(base::PathExists(sub_pref_path.Append(sub_key2)));
  prefs_.Init(prefs_dir_);
  EXPECT_FALSE(base::PathExists(prefs_dir_.Append(name_space)));
}

class MockPrefsObserver : public PrefsInterface::ObserverInterface {
 public:
  MOCK_METHOD1(OnPrefSet, void(const string&));
  MOCK_METHOD1(OnPrefDeleted, void(const string& key));
};

TEST_F(PrefsTest, ObserversCalled) {
  MockPrefsObserver mock_obserser;
  prefs_.AddObserver(kKey, &mock_obserser);

  EXPECT_CALL(mock_obserser, OnPrefSet(Eq(kKey)));
  EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
  prefs_.SetString(kKey, "value");
  testing::Mock::VerifyAndClearExpectations(&mock_obserser);

  EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
  EXPECT_CALL(mock_obserser, OnPrefDeleted(Eq(kKey)));
  prefs_.Delete(kKey);
  testing::Mock::VerifyAndClearExpectations(&mock_obserser);

  auto key1 = prefs_.CreateSubKey({"ns", "sp1", "key1"});
  prefs_.AddObserver(key1, &mock_obserser);

  EXPECT_CALL(mock_obserser, OnPrefSet(key1));
  EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
  prefs_.SetString(key1, "value");
  testing::Mock::VerifyAndClearExpectations(&mock_obserser);

  EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
  EXPECT_CALL(mock_obserser, OnPrefDeleted(Eq(key1)));
  prefs_.Delete(key1);
  testing::Mock::VerifyAndClearExpectations(&mock_obserser);

  prefs_.RemoveObserver(kKey, &mock_obserser);
}

TEST_F(PrefsTest, OnlyCalledOnObservedKeys) {
  MockPrefsObserver mock_obserser;
  const char kUnusedKey[] = "unused-key";
  prefs_.AddObserver(kUnusedKey, &mock_obserser);

  EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
  EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
  prefs_.SetString(kKey, "value");
  prefs_.Delete(kKey);

  prefs_.RemoveObserver(kUnusedKey, &mock_obserser);
}

TEST_F(PrefsTest, RemovedObserversNotCalled) {
  MockPrefsObserver mock_obserser_a, mock_obserser_b;
  prefs_.AddObserver(kKey, &mock_obserser_a);
  prefs_.AddObserver(kKey, &mock_obserser_b);
  EXPECT_CALL(mock_obserser_a, OnPrefSet(_)).Times(2);
  EXPECT_CALL(mock_obserser_b, OnPrefSet(_)).Times(1);
  EXPECT_TRUE(prefs_.SetString(kKey, "value"));
  prefs_.RemoveObserver(kKey, &mock_obserser_b);
  EXPECT_TRUE(prefs_.SetString(kKey, "other value"));
  prefs_.RemoveObserver(kKey, &mock_obserser_a);
  EXPECT_TRUE(prefs_.SetString(kKey, "yet another value"));
}

TEST_F(PrefsTest, UnsuccessfulCallsNotObserved) {
  MockPrefsObserver mock_obserser;
  const char kInvalidKey[] = "no spaces or .";
  prefs_.AddObserver(kInvalidKey, &mock_obserser);

  EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
  EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
  EXPECT_FALSE(prefs_.SetString(kInvalidKey, "value"));
  EXPECT_FALSE(prefs_.Delete(kInvalidKey));

  prefs_.RemoveObserver(kInvalidKey, &mock_obserser);
}

class MemoryPrefsTest : public ::testing::Test {
 protected:
  MemoryPrefs prefs_;
};

TEST_F(MemoryPrefsTest, BasicTest) {
  EXPECT_FALSE(prefs_.Exists(kKey));
  int64_t value = 0;
  EXPECT_FALSE(prefs_.GetInt64(kKey, &value));

  EXPECT_TRUE(prefs_.SetInt64(kKey, 1234));
  EXPECT_TRUE(prefs_.Exists(kKey));
  EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
  EXPECT_EQ(1234, value);

  EXPECT_TRUE(prefs_.Delete(kKey));
  EXPECT_FALSE(prefs_.Exists(kKey));
  EXPECT_TRUE(prefs_.Delete(kKey));

  auto key = prefs_.CreateSubKey({"ns", "sp", "sk"});
  ASSERT_TRUE(prefs_.SetInt64(key, 0));
  EXPECT_TRUE(prefs_.Exists(key));
  EXPECT_TRUE(prefs_.Delete(kKey));
}

}  // namespace chromeos_update_engine
