// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "config/config_handler.h"

#ifdef OS_WIN
#include <windows.h>
#endif  // OS_WIN

#include <string>

#include "base/file_util.h"
#include "base/logging.h"
#include "base/number_util.h"
#include "base/port.h"
#include "base/system_util.h"
#include "base/util.h"
#include "config/config.pb.h"
#include "testing/base/public/googletest.h"
#include "testing/base/public/gunit.h"

DECLARE_string(test_srcdir);
DECLARE_string(test_tmpdir);

namespace mozc {

class ConfigHandlerTest : public testing::Test {
 protected:
  virtual void SetUp() {
    SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
    default_config_filename_ = config::ConfigHandler::GetConfigFileName();
    config::Config default_config;
    config::ConfigHandler::GetDefaultConfig(&default_config);
    config::ConfigHandler::SetConfig(default_config);
  }

  virtual void TearDown() {
    config::ConfigHandler::SetConfigFileName(default_config_filename_);
    config::Config default_config;
    config::ConfigHandler::GetDefaultConfig(&default_config);
    config::ConfigHandler::SetConfig(default_config);
  }
 private:
  string default_config_filename_;
};

class ScopedSetConfigFileName {
 public:
  explicit ScopedSetConfigFileName(const string &new_name)
      : default_config_filename_(config::ConfigHandler::GetConfigFileName()) {
    config::ConfigHandler::SetConfigFileName(new_name);
  }

  ~ScopedSetConfigFileName() {
    config::ConfigHandler::SetConfigFileName(default_config_filename_);
  }

 private:
  string default_config_filename_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedSetConfigFileName);
};

TEST_F(ConfigHandlerTest, SetConfig) {
  config::Config input;
  config::Config output;

  const string config_file = FileUtil::JoinPath(FLAGS_test_tmpdir,
                                                "mozc_config_test_tmp");
  FileUtil::Unlink(config_file);
  ScopedSetConfigFileName scoped_config_file_name(config_file);
  EXPECT_EQ(config_file, config::ConfigHandler::GetConfigFileName());
  ASSERT_TRUE(config::ConfigHandler::Reload())
      << "failed to reload: " << config::ConfigHandler::GetConfigFileName();

  config::ConfigHandler::GetDefaultConfig(&input);
  input.set_incognito_mode(true);
#ifndef NO_LOGGING
  input.set_verbose_level(2);
#endif  // NO_LOGGING
  config::ConfigHandler::SetMetaData(&input);
  EXPECT_TRUE(config::ConfigHandler::SetConfig(input));
  output.Clear();
  EXPECT_TRUE(config::ConfigHandler::GetConfig(&output));
  input.mutable_general_config()->set_last_modified_time(0);
  output.mutable_general_config()->set_last_modified_time(0);
  EXPECT_EQ(input.DebugString(), output.DebugString());

  config::ConfigHandler::GetDefaultConfig(&input);
  input.set_incognito_mode(false);
#ifndef NO_LOGGING
  input.set_verbose_level(0);
#endif  // NO_LOGGING
  config::ConfigHandler::SetMetaData(&input);
  EXPECT_TRUE(config::ConfigHandler::SetConfig(input));
  output.Clear();
  EXPECT_TRUE(config::ConfigHandler::GetConfig(&output));

  input.mutable_general_config()->set_last_modified_time(0);
  output.mutable_general_config()->set_last_modified_time(0);
  EXPECT_EQ(input.DebugString(), output.DebugString());

#if defined(OS_ANDROID) && defined(CHANNEL_DEV)
  input.Clear();
  EXPECT_FALSE(input.general_config().has_upload_usage_stats());
  EXPECT_TRUE(config::ConfigHandler::SetConfig(input));
  output.Clear();
  EXPECT_TRUE(config::ConfigHandler::GetConfig(&output));
  EXPECT_TRUE(output.general_config().has_upload_usage_stats());
  EXPECT_TRUE(output.general_config().upload_usage_stats());

  input.Clear();
  input.mutable_general_config()->set_upload_usage_stats(false);
  EXPECT_TRUE(input.general_config().has_upload_usage_stats());
  EXPECT_FALSE(input.general_config().upload_usage_stats());
  EXPECT_TRUE(config::ConfigHandler::SetConfig(input));
  output.Clear();
  EXPECT_TRUE(config::ConfigHandler::GetConfig(&output));
  EXPECT_TRUE(output.general_config().has_upload_usage_stats());
  EXPECT_TRUE(output.general_config().upload_usage_stats());
#endif  // OS_ANDROID && CHANNEL_DEV
}

TEST_F(ConfigHandlerTest, SetImposedConfig) {
  config::Config input;
  config::Config output;

  const string config_file = FileUtil::JoinPath(FLAGS_test_tmpdir,
                                                "mozc_config_test_tmp");
  FileUtil::Unlink(config_file);
  ScopedSetConfigFileName scoped_config_file_name(config_file);
  ASSERT_TRUE(config::ConfigHandler::Reload())
      << "failed to reload: " << config::ConfigHandler::GetConfigFileName();

  struct Testcase {
    bool stored_config_value;
    enum {DO_NOT_IMPOSE, IMPOSE_TRUE, IMPOSE_FALSE} imposed_config_value;
    bool expected_value;
  };
  const Testcase kTestcases[] = {
    {true, Testcase::IMPOSE_TRUE, true},
    {true, Testcase::IMPOSE_FALSE, false},
    {false, Testcase::IMPOSE_TRUE, true},
    {false, Testcase::IMPOSE_FALSE, false},
    {true, Testcase::DO_NOT_IMPOSE, true},
    {false, Testcase::DO_NOT_IMPOSE, false},
  };

  for (size_t i = 0; i < arraysize(kTestcases); ++i) {
    const bool stored_config_value = kTestcases[i].stored_config_value;
    const bool expected = kTestcases[i].expected_value;

    // Set current config.
    config::ConfigHandler::GetDefaultConfig(&input);
    input.set_incognito_mode(stored_config_value);
    config::ConfigHandler::SetMetaData(&input);
    EXPECT_TRUE(config::ConfigHandler::SetConfig(input));
    // Set imposed config.
    input.Clear();
    if (kTestcases[i].imposed_config_value != Testcase::DO_NOT_IMPOSE) {
      input.set_incognito_mode(
          kTestcases[i].imposed_config_value == Testcase::IMPOSE_TRUE);
    }
    config::ConfigHandler::SetImposedConfig(input);
    // Check post-condition.
    output.Clear();
    EXPECT_TRUE(config::ConfigHandler::GetConfig(&output));
    EXPECT_EQ(expected, output.incognito_mode());
    output = config::ConfigHandler::GetConfig();
    EXPECT_EQ(expected, output.incognito_mode());
    output = config::ConfigHandler::GetStoredConfig();
    EXPECT_EQ(stored_config_value, output.incognito_mode());

    // Reload and check.
    ASSERT_TRUE(config::ConfigHandler::Reload())
        << "failed to reload: " << config::ConfigHandler::GetConfigFileName();
    output.Clear();
    EXPECT_TRUE(config::ConfigHandler::GetConfig(&output));
    EXPECT_EQ(expected, output.incognito_mode());
    output = config::ConfigHandler::GetConfig();
    EXPECT_EQ(expected, output.incognito_mode());
    output = config::ConfigHandler::GetStoredConfig();
    EXPECT_EQ(stored_config_value, output.incognito_mode());

    // Unset imposed config.
    input.Clear();
    config::ConfigHandler::SetImposedConfig(input);
    // Check post-condition.
    output.Clear();
    EXPECT_TRUE(config::ConfigHandler::GetConfig(&output));
    EXPECT_EQ(stored_config_value, output.incognito_mode());
    output = config::ConfigHandler::GetConfig();
    EXPECT_EQ(stored_config_value, output.incognito_mode());
    output = config::ConfigHandler::GetStoredConfig();
    EXPECT_EQ(stored_config_value, output.incognito_mode());
  }
}

TEST_F(ConfigHandlerTest, ConfigFileNameConfig) {
  const string config_file = string("config")
      + NumberUtil::SimpleItoa(config::CONFIG_VERSION);

  const string filename = FileUtil::JoinPath(FLAGS_test_tmpdir, config_file);
  FileUtil::Unlink(filename);
  config::Config input;
  config::ConfigHandler::SetConfig(input);
  FileUtil::FileExists(filename);
}

TEST_F(ConfigHandlerTest, SetConfigFileName) {
  config::Config mozc_config;
  const bool default_incognito_mode = mozc_config.incognito_mode();
  mozc_config.set_incognito_mode(!default_incognito_mode);
  config::ConfigHandler::SetConfig(mozc_config);
  // ScopedSetConfigFileName internally calls SetConfigFileName.
  ScopedSetConfigFileName scoped_config_file_name(
      "memory://set_config_file_name_test.db");
  // After SetConfigFileName called, settings are set as default.
  EXPECT_EQ(default_incognito_mode, GET_CONFIG(incognito_mode));
}

#ifndef OS_ANDROID
// Temporarily disable this test because FileUtil::CopyFile fails on
// Android for some reason.
// TODO(yukawa): Enable this test on Android.
TEST_F(ConfigHandlerTest, LoadTestConfig) {
  const char kPathPrefix[] = "";
  const char KDataDir[] = "data/test/config";
  // TODO(yukawa): Generate test data automatically so that we can keep
  //     the compatibility among variety of config files.
  // TODO(yukawa): Enumerate test data in the directory automatically.
  const char *kDataFiles[] = {
    "linux_config1.db",
    "mac_config1.db",
    "win_config1.db",
  };

  for (size_t i = 0; i < arraysize(kDataFiles); ++i) {
    const char *file_name = kDataFiles[i];
    const string &src_path = FileUtil::JoinPath(
        FileUtil::JoinPath(FLAGS_test_srcdir, kPathPrefix),
        FileUtil::JoinPath(KDataDir, file_name));
    const string &dest_path = FileUtil::JoinPath(
        SystemUtil::GetUserProfileDirectory(), file_name);
    ASSERT_TRUE(FileUtil::CopyFile(src_path, dest_path))
        << "Copy failed: " << src_path << " to " << dest_path;

    ScopedSetConfigFileName scoped_config_file_name(
        "user://" + string(file_name));
    ASSERT_TRUE(config::ConfigHandler::Reload())
        << "failed to reload: " << config::ConfigHandler::GetConfigFileName();

    config::Config default_config;
    EXPECT_TRUE(config::ConfigHandler::GetConfig(&default_config))
        << "failed to GetConfig from: " << file_name;

#ifdef OS_WIN
    // Reset the file attributes since it may contain FILE_ATTRIBUTE_READONLY.
    wstring wdest_path;
    Util::UTF8ToWide(dest_path.c_str(), &wdest_path);
    ::SetFileAttributesW(wdest_path.c_str(), FILE_ATTRIBUTE_NORMAL);
#endif  // OS_WIN

    // Remove test file just in case.
    ASSERT_TRUE(FileUtil::Unlink(dest_path));
    EXPECT_FALSE(FileUtil::FileExists(dest_path));
  }
}
#endif  // !OS_ANDROID

TEST_F(ConfigHandlerTest, GetDefaultConfig) {
  config::Config output;

  output.Clear();
  config::ConfigHandler::GetDefaultConfig(&output);
#ifdef OS_MACOSX
  EXPECT_EQ(output.session_keymap(), config::Config::KOTOERI);
#else  // OS_MACOSX
  EXPECT_EQ(output.session_keymap(), config::Config::MSIME);
#endif
  EXPECT_EQ(output.character_form_rules_size(), 13);

  struct TestCase {
    const char *group;
    config::Config::CharacterForm preedit_character_form;
    config::Config::CharacterForm conversion_character_form;
  };
  const TestCase testcases[] = {
     // "ア"
    {"\xE3\x82\xA2", config::Config::FULL_WIDTH, config::Config::FULL_WIDTH},
    {"A", config::Config::FULL_WIDTH, config::Config::LAST_FORM},
    {"0", config::Config::FULL_WIDTH, config::Config::LAST_FORM},
    {"(){}[]", config::Config::FULL_WIDTH, config::Config::LAST_FORM},
    {".,", config::Config::FULL_WIDTH, config::Config::LAST_FORM},
    // "。、",
    {"\xE3\x80\x82\xE3\x80\x81",
      config::Config::FULL_WIDTH, config::Config::FULL_WIDTH},
    // "・「」"
    {"\xE3\x83\xBB\xE3\x80\x8C\xE3\x80\x8D",
      config::Config::FULL_WIDTH, config::Config::FULL_WIDTH},
    {"\"'", config::Config::FULL_WIDTH, config::Config::LAST_FORM},
    {":;", config::Config::FULL_WIDTH, config::Config::LAST_FORM},
    {"#%&@$^_|`\\", config::Config::FULL_WIDTH, config::Config::LAST_FORM},
    {"~", config::Config::FULL_WIDTH, config::Config::LAST_FORM},
    {"<>=+-/*", config::Config::FULL_WIDTH, config::Config::LAST_FORM},
    {"?!", config::Config::FULL_WIDTH, config::Config::LAST_FORM},
  };
  EXPECT_EQ(output.character_form_rules_size(), arraysize(testcases));
  for (size_t i = 0; i < arraysize(testcases); ++i) {
    EXPECT_EQ(output.character_form_rules(i).group(),
              testcases[i].group);
    EXPECT_EQ(output.character_form_rules(i).preedit_character_form(),
              testcases[i].preedit_character_form);
    EXPECT_EQ(output.character_form_rules(i).conversion_character_form(),
              testcases[i].conversion_character_form);
  }

#if defined(OS_ANDROID) && defined(CHANNEL_DEV)
  EXPECT_TRUE(output.general_config().has_upload_usage_stats());
  EXPECT_TRUE(output.general_config().upload_usage_stats());
#endif  // OS_ANDROID && CHANNEL_DEV
}
}  // namespace mozc
