// Copyright 2015 The Crashpad Authors
//
// 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 "client/settings.h"

#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/scoped_temp_dir.h"
#include "util/file/file_io.h"

namespace crashpad {
namespace test {
namespace {

class SettingsTest : public testing::Test {
 public:
  SettingsTest() = default;

  SettingsTest(const SettingsTest&) = delete;
  SettingsTest& operator=(const SettingsTest&) = delete;

  base::FilePath settings_path() {
    return temp_dir_.path().Append(FILE_PATH_LITERAL("settings"));
  }

  Settings* settings() { return &settings_; }

  void InitializeBadFile() {
    ScopedFileHandle handle(
        LoggingOpenFileForWrite(settings_path(),
                                FileWriteMode::kTruncateOrCreate,
                                FilePermissions::kWorldReadable));
    ASSERT_TRUE(handle.is_valid());

    static constexpr char kBuf[] = "test bad file";
    ASSERT_TRUE(LoggingWriteFile(handle.get(), kBuf, sizeof(kBuf)));
    handle.reset();
  }

 protected:
  // testing::Test:
  void SetUp() override {
    ASSERT_TRUE(settings()->Initialize(settings_path()));
  }

 private:
  ScopedTempDir temp_dir_;
  Settings settings_;
};

TEST_F(SettingsTest, ClientID) {
  UUID client_id;
  EXPECT_TRUE(settings()->GetClientID(&client_id));
  EXPECT_NE(client_id, UUID());

  Settings local_settings;
  EXPECT_TRUE(local_settings.Initialize(settings_path()));
  UUID actual;
  EXPECT_TRUE(local_settings.GetClientID(&actual));
  EXPECT_EQ(actual, client_id);
}

TEST_F(SettingsTest, UploadsEnabled) {
  bool enabled = true;
  // Default value is false.
  EXPECT_TRUE(settings()->GetUploadsEnabled(&enabled));
  EXPECT_FALSE(enabled);

  EXPECT_TRUE(settings()->SetUploadsEnabled(true));
  EXPECT_TRUE(settings()->GetUploadsEnabled(&enabled));
  EXPECT_TRUE(enabled);

  Settings local_settings;
  EXPECT_TRUE(local_settings.Initialize(settings_path()));
  enabled = false;
  EXPECT_TRUE(local_settings.GetUploadsEnabled(&enabled));
  EXPECT_TRUE(enabled);

  EXPECT_TRUE(settings()->SetUploadsEnabled(false));
  EXPECT_TRUE(settings()->GetUploadsEnabled(&enabled));
  EXPECT_FALSE(enabled);

  enabled = true;
  EXPECT_TRUE(local_settings.GetUploadsEnabled(&enabled));
  EXPECT_FALSE(enabled);
}

TEST_F(SettingsTest, LastUploadAttemptTime) {
  time_t actual = -1;
  EXPECT_TRUE(settings()->GetLastUploadAttemptTime(&actual));
  // Default value is 0.
  EXPECT_EQ(actual, 0);

  const time_t expected = time(nullptr);
  EXPECT_TRUE(settings()->SetLastUploadAttemptTime(expected));
  EXPECT_TRUE(settings()->GetLastUploadAttemptTime(&actual));
  EXPECT_EQ(actual, expected);

  Settings local_settings;
  EXPECT_TRUE(local_settings.Initialize(settings_path()));
  actual = -1;
  EXPECT_TRUE(local_settings.GetLastUploadAttemptTime(&actual));
  EXPECT_EQ(actual, expected);
}

// The following tests write a corrupt settings file and test the recovery
// operation.

TEST_F(SettingsTest, BadFileOnInitialize) {
  InitializeBadFile();

  Settings settings;
  EXPECT_TRUE(settings.Initialize(settings_path()));
}

TEST_F(SettingsTest, BadFileOnGet) {
  InitializeBadFile();

  UUID client_id;
  EXPECT_TRUE(settings()->GetClientID(&client_id));
  EXPECT_NE(client_id, UUID());

  Settings local_settings;
  EXPECT_TRUE(local_settings.Initialize(settings_path()));
  UUID actual;
  EXPECT_TRUE(local_settings.GetClientID(&actual));
  EXPECT_EQ(actual, client_id);
}

TEST_F(SettingsTest, BadFileOnSet) {
  InitializeBadFile();

  EXPECT_TRUE(settings()->SetUploadsEnabled(true));
  bool enabled = false;
  EXPECT_TRUE(settings()->GetUploadsEnabled(&enabled));
  EXPECT_TRUE(enabled);
}

TEST_F(SettingsTest, UnlinkFile) {
  UUID client_id;
  EXPECT_TRUE(settings()->GetClientID(&client_id));
  EXPECT_TRUE(settings()->SetUploadsEnabled(true));
  EXPECT_TRUE(settings()->SetLastUploadAttemptTime(time(nullptr)));

#if BUILDFLAG(IS_WIN)
  EXPECT_EQ(_wunlink(settings_path().value().c_str()), 0)
      << ErrnoMessage("_wunlink");
#else
  EXPECT_EQ(unlink(settings_path().value().c_str()), 0)
      << ErrnoMessage("unlink");
#endif

  Settings local_settings;
  EXPECT_TRUE(local_settings.Initialize(settings_path()));
  UUID new_client_id;
  EXPECT_TRUE(local_settings.GetClientID(&new_client_id));
  EXPECT_NE(new_client_id, client_id);

  // Check that all values are reset.
  bool enabled = true;
  EXPECT_TRUE(local_settings.GetUploadsEnabled(&enabled));
  EXPECT_FALSE(enabled);

  time_t time = -1;
  EXPECT_TRUE(local_settings.GetLastUploadAttemptTime(&time));
  EXPECT_EQ(time, 0);
}

}  // namespace
}  // namespace test
}  // namespace crashpad
