// Copyright 2016 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.

// Tests for the CrosConfig library, which provides access to the
// Chrome OS model configuration.

#include <cstdlib>
#include <string>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <gtest/gtest.h>
#include "chromeos-config/libcros_config/cros_config.h"
#include "chromeos-config/libcros_config/cros_config_fallback.h"
#include "chromeos-config/libcros_config/identity.h"

namespace {
constexpr char kTestFile[] = "test.json";
constexpr char kTestFileArm[] = "test_arm.json";
constexpr char kTestFileInvalid[] = "invalid_file.json";
}  // namespace

class CrosConfigTest : public testing::Test {
 protected:
  void InitConfig(const std::string name = "Another",
                  int sku_id = -1,
                  std::string whitelabel_name = "") {
    base::FilePath filepath(kTestFile);
    ASSERT_TRUE(cros_config_.InitForTest(sku_id, filepath,
                                         brillo::SystemArchitecture::kX86, name,
                                         whitelabel_name));
  }

  void InitConfigArm(const std::string device_name = "google,some",
                     int sku_id = -1,
                     std::string whitelabel_name = "") {
    base::FilePath filepath(kTestFileArm);
    ASSERT_TRUE(cros_config_.InitForTest(sku_id, filepath,
                                         brillo::SystemArchitecture::kArm,
                                         device_name, whitelabel_name));
  }

  brillo::CrosConfig cros_config_;
};

TEST_F(CrosConfigTest, CheckMissingFile) {
  base::FilePath filepath(kTestFileInvalid);
  EXPECT_FALSE(cros_config_.InitForTest(
      -1, filepath, brillo::SystemArchitecture::kX86, "no-model", ""));
}

TEST_F(CrosConfigTest, CheckUnknownModel) {
  base::FilePath filepath(kTestFile);
  EXPECT_FALSE(cros_config_.InitForTest(
      -1, filepath, brillo::SystemArchitecture::kX86, "no-model", ""));
}

TEST_F(CrosConfigTest, Check111NoInit) {
  std::string val;
  EXPECT_FALSE(cros_config_.GetString("/", "wallpaper", &val));
}

TEST_F(CrosConfigTest, CheckWrongPath) {
  InitConfig();
  std::string val;
  EXPECT_FALSE(cros_config_.GetString("/wibble", "wallpaper", &val));
}

TEST_F(CrosConfigTest, CheckBadString) {
  InitConfig();
  std::string val;
  EXPECT_FALSE(cros_config_.GetString("/", "string-list", &val));
}

TEST_F(CrosConfigTest, CheckGoodStringRoot) {
  InitConfig();
  std::string val;
  ASSERT_TRUE(cros_config_.GetString("/", "wallpaper", &val));
  EXPECT_EQ("default", val);
}

TEST_F(CrosConfigTest, CheckGoodStringNonRoot) {
  InitConfig();
  std::string val;
  ASSERT_TRUE(cros_config_.GetString("/identity", "smbios-name-match", &val));
  EXPECT_EQ("Another", val);
}

TEST_F(CrosConfigTest, CheckSMBIOSMatchInsensitive) {
  InitConfig("AnOtHeR");
  std::string val;
  ASSERT_TRUE(cros_config_.GetString("/", "name", &val));
  EXPECT_EQ("another", val);
}

TEST_F(CrosConfigTest, CheckEmptyPathError) {
  InitConfig();
  std::string val;
  ASSERT_FALSE(cros_config_.GetString("", "wallpaper", &val));
  EXPECT_EQ("", val);
}

TEST_F(CrosConfigTest, CheckPathWithoutSlashError) {
  InitConfig();
  std::string val;
  ASSERT_FALSE(cros_config_.GetString("noslash", "wallpaper", &val));
  EXPECT_EQ("", val);
}

TEST_F(CrosConfigTest, CheckUiPowerPosition) {
  InitConfig("Some", 1);
  std::string val;
  ASSERT_TRUE(cros_config_.GetString("/ui/power-button", "edge", &val));
  EXPECT_EQ("left", val);
  ASSERT_TRUE(cros_config_.GetString("/ui/power-button", "position", &val));
  EXPECT_EQ("0.3", val);
}

TEST_F(CrosConfigTest, CheckCameraCount) {
  InitConfig("Some", 0);
  std::string val;
  ASSERT_TRUE(cros_config_.GetString("/camera", "count", &val));
  EXPECT_EQ("1", val);
}

TEST_F(CrosConfigTest, CheckDeviceIndex0) {
  InitConfig("Some", 0);

  int device_index;
  ASSERT_TRUE(cros_config_.GetDeviceIndex(&device_index));
  EXPECT_EQ(0, device_index);
}

TEST_F(CrosConfigTest, CheckDeviceIndex1) {
  InitConfig("Some", 1);

  int device_index;
  ASSERT_TRUE(cros_config_.GetDeviceIndex(&device_index));
  EXPECT_EQ(1, device_index);
}

TEST_F(CrosConfigTest, CheckDeviceIndex2) {
  InitConfig("Some", 2);

  int device_index;
  ASSERT_TRUE(cros_config_.GetDeviceIndex(&device_index));
  EXPECT_EQ(2, device_index);
}

TEST_F(CrosConfigTest, CheckDeviceIndex3) {
  InitConfig("Another", 0);

  int device_index;
  ASSERT_TRUE(cros_config_.GetDeviceIndex(&device_index));
  EXPECT_EQ(3, device_index);
}

TEST_F(CrosConfigTest, CheckWriteFallbackFS) {
  base::FilePath tempdir;
  ASSERT_TRUE(base::CreateNewTempDirectory("cros_config_test", &tempdir));

  brillo::CrosConfigFallback fallback;
  EXPECT_TRUE(fallback.WriteConfigFS(tempdir));

  std::string contents;
  ASSERT_TRUE(base::ReadFileToString(
      tempdir.Append("firmware").Append("image-name"), &contents));
  EXPECT_EQ("test_mosys_model_string", contents);

  ASSERT_TRUE(base::ReadFileToString(
      tempdir.Append("ui").Append("help-content-id"), &contents));
  EXPECT_EQ("ABC123-MODEL", contents);
}

int main(int argc, char** argv) {
  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_FILE;
  settings.log_file_path = "log.test";
  settings.lock_log = logging::DONT_LOCK_LOG_FILE;
  settings.delete_old = logging::DELETE_OLD_LOG_FILE;
  logging::InitLogging(settings);
  logging::SetMinLogLevel(-3);

  int status = system("exec ./chromeos-config-test-setup.sh");
  if (status != 0) {
    LOG(ERROR) << "Failed to run ./chromeos-config-test-setup.sh";
    return EXIT_FAILURE;
  }

  // $SRC/testbin contains a fake mosys which is used by the tests
  const char* src_path = getenv("SRC");
  if (!src_path || !src_path[0]) {
    LOG(ERROR) << "SRC must be set in the environment";
    return EXIT_FAILURE;
  }

  std::string new_path(src_path);
  new_path += "/testbin";

  if (setenv("PATH", new_path.c_str(), true) < 0) {
    LOG(ERROR) << "Failed to set PATH";
    return EXIT_FAILURE;
  }

  testing::InitGoogleTest(&argc, argv);

  return RUN_ALL_TESTS();
}
