// Copyright 2020 The Cobalt Authors. All Rights Reserved.
//
// 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 "components/update_client/cobalt_slot_management.h"

#include <sys/stat.h>

#include <algorithm>
#include <vector>

#include "base/strings/string_util.h"
#include "starboard/common/file.h"
#include "starboard/common/time.h"
#include "starboard/extension/free_space.h"
#include "starboard/loader_app/app_key_files.h"
#include "starboard/loader_app/drain_file.h"
#include "starboard/loader_app/drain_file_helper.h"
#include "starboard/loader_app/installation_manager.h"
#include "starboard/loader_app/system_get_extension_shim.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace update_client {
namespace {

constexpr char kTestAppKey1[] = "test_key1";
constexpr char kTestAppKey2[] = "test_key2";
constexpr char kManifestV1[] = R"json({
  "manifest_version": 2,
  "name": "Cobalt",
  "description": "Cobalt",
  "version": "1.1.0"
})json";

constexpr char kManifestV2[] = R"json(
{
  "manifest_version": 2,
  "name": "Cobalt",
  "description": "Cobalt",
  "version": "1.2.0"
})json";

class CobaltSlotManagementTest : public testing::Test {
 protected:
  void SetUp() override {
    std::vector<char> buf(kSbFileMaxPath);
    storage_path_implemented_ = SbSystemGetPath(kSbSystemPathStorageDirectory,
                                                buf.data(), kSbFileMaxPath);
    if (!storage_path_implemented_) {
      return;
    }

    storage_path_ = buf.data();
    ASSERT_TRUE(!storage_path_.empty());

    starboard::SbFileDeleteRecursive(storage_path_.c_str(), true);
    ImInitialize(3, kTestAppKey1);
    api_ = static_cast<const CobaltExtensionInstallationManagerApi*>(
        starboard::loader_app::SbSystemGetExtensionShim(
            kCobaltExtensionInstallationManagerName));
  }

  void TearDown() override {
    starboard::SbFileDeleteRecursive(storage_path_.c_str(), true);
    ImUninitialize();
  }

  void CreateManifest(const char* slot_path,
                      const char* data,
                      size_t data_length) {
    std::string manifest1_path = storage_path_;
    manifest1_path += kSbFileSepString;
    manifest1_path += slot_path;
    manifest1_path += kSbFileSepString;
    manifest1_path += "manifest.json";

    ASSERT_TRUE(SbFileAtomicReplace(manifest1_path.c_str(), data, data_length));
  }

  const CobaltExtensionInstallationManagerApi* api_;
  bool storage_path_implemented_;
  std::string storage_path_;
};

TEST_F(CobaltSlotManagementTest, Init) {
  if (!storage_path_implemented_) {
    return;
  }
  CobaltSlotManagement cobalt_slot_management;
  ASSERT_TRUE(cobalt_slot_management.Init(api_));
}

TEST_F(CobaltSlotManagementTest, NegativeInit) {
  if (!storage_path_implemented_) {
    return;
  }
  CobaltSlotManagement cobalt_slot_management;
  ASSERT_FALSE(cobalt_slot_management.Init(nullptr));
}

TEST_F(CobaltSlotManagementTest, SelectEmptySlot) {
  if (!storage_path_implemented_) {
    return;
  }
  CobaltSlotManagement cobalt_slot_management;
  ASSERT_TRUE(cobalt_slot_management.Init(api_));
  base::FilePath dir;
  ASSERT_TRUE(cobalt_slot_management.SelectSlot(&dir));
  ASSERT_TRUE(DrainFileIsAppDraining(dir.value().c_str(), kTestAppKey1));
  ASSERT_TRUE(base::EndsWith(dir.value(), "installation_1",
                             base::CompareCase::SENSITIVE));
}

TEST_F(CobaltSlotManagementTest, SelectSlotBailsIfOtherAppIsDraining) {
  if (!storage_path_implemented_) {
    return;
  }

  CobaltSlotManagement cobalt_slot_management;
  std::string slot_path = storage_path_;
  slot_path += kSbFileSepString;
  slot_path += "installation_1";

  // If there is is non-expired drain file from
  // different app the current app should bail out.
  ASSERT_TRUE(DrainFileTryDrain(slot_path.c_str(), kTestAppKey2));
  ASSERT_TRUE(cobalt_slot_management.Init(api_));

  base::FilePath dir;
  ASSERT_FALSE(cobalt_slot_management.SelectSlot(&dir));
}

TEST_F(CobaltSlotManagementTest, SelectMinVersionSlot) {
  if (!storage_path_implemented_) {
    return;
  }

  // In slot 2 create manifest v1.
  CreateManifest("installation_2", kManifestV1, strlen(kManifestV1));

  // In slot 1 create manifest v2.
  CreateManifest("installation_1", kManifestV2, strlen(kManifestV2));

  CobaltSlotManagement cobalt_slot_management;
  ASSERT_TRUE(cobalt_slot_management.Init(api_));
  base::FilePath dir;
  cobalt_slot_management.SelectSlot(&dir);
  ASSERT_TRUE(DrainFileIsAppDraining(dir.value().c_str(), kTestAppKey1));
  LOG(INFO) << "dir=" << dir;

  ASSERT_TRUE(base::EndsWith(dir.value(), "installation_2",
                             base::CompareCase::SENSITIVE));
}

TEST_F(CobaltSlotManagementTest, ConfirmSlot) {
  if (!storage_path_implemented_) {
    return;
  }

  ImRollForward(1);
  ImDecrementInstallationNumTries(1);
  ASSERT_LE(ImGetInstallationNumTriesLeft(1), IM_MAX_NUM_TRIES);
  ImMarkInstallationSuccessful(1);
  ASSERT_EQ(IM_INSTALLATION_STATUS_SUCCESS, ImGetInstallationStatus(1));
  CobaltSlotManagement cobalt_slot_management;
  ASSERT_TRUE(cobalt_slot_management.Init(api_));
  base::FilePath dir;
  ASSERT_TRUE(cobalt_slot_management.SelectSlot(&dir));
  LOG(INFO) << "dir=" << dir;

  ASSERT_TRUE(base::EndsWith(dir.value(), "installation_1",
                             base::CompareCase::SENSITIVE));

  ASSERT_TRUE(DrainFileIsAppDraining(dir.value().c_str(), kTestAppKey1));

  ASSERT_TRUE(cobalt_slot_management.ConfirmSlot(dir));

  ASSERT_EQ(IM_INSTALLATION_STATUS_NOT_SUCCESS, ImGetInstallationStatus(1));
  ASSERT_EQ(IM_MAX_NUM_TRIES, ImGetInstallationNumTriesLeft(1));
}

// Tests the "racing updaters" scenario.
TEST_F(CobaltSlotManagementTest, ConfirmSlotBailsIfOtherAppStartedDrainFirst) {
  if (!storage_path_implemented_) {
    return;
  }

  CobaltSlotManagement cobalt_slot_management;
  std::string slot_path = storage_path_;
  slot_path += kSbFileSepString;
  slot_path += "installation_1";
  ASSERT_TRUE(cobalt_slot_management.Init(api_));
  base::FilePath dir;
  ASSERT_TRUE(cobalt_slot_management.SelectSlot(&dir));

  // In order to be higher ranked, the other app's drain file needs to be older
  // but not expired.
  int64_t current_time_us =
      starboard::PosixTimeToWindowsTime(starboard::CurrentPosixTime());
  starboard::loader_app::ScopedDrainFile racing_drain_file(
      slot_path, kTestAppKey2,
      current_time_us - (kDrainFileMaximumAgeUsec / 2));

  ASSERT_FALSE(cobalt_slot_management.ConfirmSlot(dir));
}

TEST_F(CobaltSlotManagementTest, CleanupAllDrainFiles) {
  if (!storage_path_implemented_) {
    return;
  }
  CobaltSlotManagement cobalt_slot_management;
  ASSERT_TRUE(cobalt_slot_management.Init(api_));
  base::FilePath dir;
  ASSERT_TRUE(cobalt_slot_management.SelectSlot(&dir));
  ASSERT_TRUE(DrainFileIsAppDraining(dir.value().c_str(), kTestAppKey1));
  cobalt_slot_management.CleanupAllDrainFiles();
  ASSERT_FALSE(DrainFileIsAppDraining(dir.value().c_str(), kTestAppKey1));
}

TEST_F(CobaltSlotManagementTest, CobaltFinishInstallation) {
  std::string slot_path = storage_path_;
  slot_path += kSbFileSepString;
  slot_path += "installation_1";
  std::string good_file_path =
      starboard::loader_app::GetGoodAppKeyFilePath(slot_path, kTestAppKey1);

  ImRollForward(2);

  // Cleanup pending requests for roll forward.
  ASSERT_EQ(IM_SUCCESS, ImRollForwardIfNeeded());

  ASSERT_EQ(2, ImGetCurrentInstallationIndex());
  struct stat file_info;
  ASSERT_FALSE(stat(good_file_path.c_str(), &file_info) == 0);
  ASSERT_TRUE(CobaltFinishInstallation(api_, 1, slot_path, kTestAppKey1));
  ASSERT_TRUE(stat(good_file_path.c_str(), &file_info) == 0);
  ASSERT_EQ(IM_SUCCESS, ImRollForwardIfNeeded());
  ASSERT_EQ(1, ImGetCurrentInstallationIndex());
}

TEST_F(CobaltSlotManagementTest, GoodCobaltQuickUpdate) {
  // In slot 1 create manifest v1.
  CreateManifest("installation_1", kManifestV1, strlen(kManifestV1));

  // In slot 2 create manifest v2.
  CreateManifest("installation_2", kManifestV2, strlen(kManifestV2));

  // Mark slot 2 good for app 2.
  std::string slot_path = storage_path_;
  slot_path += kSbFileSepString;
  slot_path += "installation_2";
  std::string good_file_path =
      starboard::loader_app::GetGoodAppKeyFilePath(slot_path, kTestAppKey2);
  starboard::loader_app::CreateAppKeyFile(good_file_path);
  base::Version version("1.1.0");
  ASSERT_TRUE(CobaltQuickUpdate(api_, version));
}

TEST_F(CobaltSlotManagementTest, NegativeCobaltQuickUpdateBadVersion) {
  base::Version version;
  ASSERT_FALSE(CobaltQuickUpdate(api_, version));
}

TEST_F(CobaltSlotManagementTest, NegativeCobaltQuickUpdate) {
  base::Version version("1.0.0");
  ASSERT_FALSE(CobaltQuickUpdate(api_, version));
}

TEST_F(CobaltSlotManagementTest, CobaltSkipUpdateNoInstallationMoreSpace) {
  ASSERT_FALSE(
      CobaltSkipUpdate(api_, 1024 /* min */, 1025 /* free */, 0 /* cleanup */));
}

TEST_F(CobaltSlotManagementTest, CobaltSkipUpdateNoInstallationExactSpace) {
  ASSERT_FALSE(
      CobaltSkipUpdate(api_, 1024 /* min */, 1024 /* free */, 0 /* cleanup */));
}

TEST_F(CobaltSlotManagementTest, CobaltSkipUpdateNoInstallationNotEnoughSpace) {
  ASSERT_TRUE(
      CobaltSkipUpdate(api_, 1024 /* min */, 1023 /* free */, 0 /* cleanup */));
}

TEST_F(CobaltSlotManagementTest, CobaltSkipUpdateWithInstallationMoreSpace) {
  ASSERT_FALSE(
      CobaltSkipUpdate(api_, 1024 /* min */, 1024 /* free */, 1 /* cleanup */));
}

TEST_F(CobaltSlotManagementTest, CobaltSkipUpdateWithInstallationExactSpace) {
  ASSERT_FALSE(
      CobaltSkipUpdate(api_, 1024 /* min */, 1023 /* free */, 1 /* cleanup */));
}

TEST_F(CobaltSlotManagementTest,
       CobaltSkipUpdateWithInstallationNotEnoughSpace) {
  ASSERT_TRUE(
      CobaltSkipUpdate(api_, 1024 /* min */, 1022 /* free */, 1 /* cleanup */));
}

TEST_F(CobaltSlotManagementTest, CobaltInstallationCleanupSizeNoInstallation) {
  uint64_t size = CobaltInstallationCleanupSize(api_);
  ASSERT_EQ(size, 0);
}

TEST_F(CobaltSlotManagementTest,
       CobaltInstallationCleanupSizeTwoInstallations) {
  int len1 = strlen(kManifestV1);
  int len2 = strlen(kManifestV2);
  ASSERT_NE(len1, len2);

  CreateManifest("installation_1", kManifestV2, len1);
  CreateManifest("installation_2", kManifestV1, len2);

  uint64_t size = CobaltInstallationCleanupSize(api_);
  ASSERT_EQ(size, std::min(len1, len2));
}
}  // namespace

}  // namespace update_client
