// Copyright 2023 The Bazel 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 <stdlib.h>

#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "file/base/filesystem.h"
#include "file/base/helpers.h"
#include "file/base/path.h"
#include "file/util/temp_path.h"
#include "file/zipfile/zipfilewriter.h"
#include "src/main/cpp/archive_utils.h"
#include "src/main/cpp/bazel_startup_options.h"
#include "googlemock/include/gmock/gmock.h"
#include "googletest/include/gtest/gtest.h"
#include "absl/status/statusor.h"
#include "absl/time/time.h"
#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/blaze_util_platform.h"
#include "src/main/cpp/util/exit_code.h"
#include "src/main/cpp/util/file_platform.h"
#include "src/main/cpp/workspace_layout.h"
#include "util/task/status_macros.h"

using ::testing::Gt;
using ::testing::status::IsOkAndHolds;

namespace blaze {

static std::vector<std::pair<std::string, std::string>>
get_archive_path_to_contents(std::string expected_install_md5) {
  std::vector<std::pair<std::string, std::string>> archive_path_to_contents;
  archive_path_to_contents.push_back(std::make_pair("foo", "foo content"));
  archive_path_to_contents.push_back(std::make_pair("bar", "bar content"));
  archive_path_to_contents.push_back(
      std::make_pair("path/to/subdir/baz", "baz content"));
  archive_path_to_contents.push_back(
      std::make_pair("install_base_key", expected_install_md5));
  return archive_path_to_contents;
}

static std::vector<std::string> get_archive_paths() {
  std::vector<std::string> archive_paths;
  archive_paths.push_back("foo");
  archive_paths.push_back("bar");
  archive_paths.push_back("path/to/subdir/baz");
  return archive_paths;
}

static absl::StatusOr<std::string> MakeZipAndReturnInstallBase(
    absl::string_view path, std::vector<std::pair<std::string, std::string>>
                                blaze_zip_file_to_contents) {
  ASSIGN_OR_RETURN(auto writer,
                   file_zipfile::ZipfileWriter::Create(path, file::Defaults()));
  for (const auto file_and_contents : blaze_zip_file_to_contents) {
    writer->AddFileFromString(file_and_contents.first,
                              file_and_contents.second);
  }
  RETURN_IF_ERROR(writer->CloseWithStatus(file::Defaults()));
  return "install_base";
}

static void set_startup_options(BazelStartupOptions &startup_options,
                                std::string blaze_path,
                                std::string output_dir) {
  std::string error;
  const std::string install_base_flag = "--install_base=" + output_dir;
  const std::vector<RcStartupFlag> flags{
      RcStartupFlag("somewhere", install_base_flag)};
  const blaze_exit_code::ExitCode ec =
      startup_options.ProcessArgs(flags, &error);
  ASSERT_EQ(ec, blaze_exit_code::SUCCESS)
      << "ProcessArgs failed with error " << error;
}

auto get_mtime = [](absl::string_view path) -> absl::StatusOr<absl::Time> {
  ASSIGN_OR_RETURN(
      const auto stat,
      file::Stat(path, file::StatMask(tech::file::STAT_MTIME_NSECS)));
  return absl::FromUnixNanos(stat.mtime_nsecs());
};

class BlazeArchiveTest : public ::testing::Test {
 protected:
  BlazeArchiveTest() {}

  virtual ~BlazeArchiveTest() {}

  void SetUp() override {
    expected_install_md5 = "expected_install_md5";
    blaze_zip_file_to_contents =
        get_archive_path_to_contents(expected_install_md5);
    archive_contents = get_archive_paths();
    blaze_path = file::JoinPath(temp_.path(), "blaze");
    ASSERT_OK_AND_ASSIGN(
        install_base,
        MakeZipAndReturnInstallBase(blaze_path, blaze_zip_file_to_contents));
    output_dir = file::JoinPath(temp_.path(), install_base);
  }

  const TempPath temp_{TempPath::Local};

  std::vector<std::pair<std::string, std::string>> blaze_zip_file_to_contents;
  std::vector<std::string> archive_contents;

  std::string expected_install_md5;
  std::string blaze_path;
  std::string install_base;
  std::string output_dir;
};

TEST_F(BlazeArchiveTest, TestZipExtractionAndFarOutMTimes) {
  std::unique_ptr<blaze::WorkspaceLayout> workspace_layout(
      new blaze::WorkspaceLayout());
  BazelStartupOptions startup_options(workspace_layout.get());
  set_startup_options(startup_options, blaze_path, output_dir);
  LoggingInfo logging_info(blaze_path, blaze::GetMillisecondsMonotonic());

  std::optional<DurationMillis> extraction_time =
      ExtractData(blaze_path, archive_contents, expected_install_md5,
                  startup_options, &logging_info);

  ASSERT_TRUE(extraction_time.has_value());

  const std::string foo_path = file::JoinPath(output_dir, "foo");
  const std::string bar_path = file::JoinPath(output_dir, "bar");
  const std::string baz_path = file::JoinPath(output_dir, "path/to/subdir/baz");

  EXPECT_THAT(file::GetContents(foo_path, file::Defaults()),
              IsOkAndHolds("foo content"));
  EXPECT_THAT(file::GetContents(bar_path, file::Defaults()),
              IsOkAndHolds("bar content"));
  EXPECT_THAT(file::GetContents(baz_path, file::Defaults()),
              IsOkAndHolds("baz content"));

  EXPECT_TRUE(IsUntampered(blaze_util::Path(foo_path)));
  EXPECT_TRUE(IsUntampered(blaze_util::Path(bar_path)));
  EXPECT_TRUE(IsUntampered(blaze_util::Path(baz_path)));

  const auto far_future = absl::Now() + absl::Hours(24 * 365 * 9);
  EXPECT_THAT(get_mtime(foo_path), IsOkAndHolds(Gt(far_future)));
  EXPECT_THAT(get_mtime(bar_path), IsOkAndHolds(Gt(far_future)));
  EXPECT_THAT(get_mtime(baz_path), IsOkAndHolds(Gt(far_future)));
}

TEST_F(BlazeArchiveTest, TestNoDataExtractionIfInstallBaseExists) {
  std::unique_ptr<blaze::WorkspaceLayout> workspace_layout(
      new blaze::WorkspaceLayout());
  BazelStartupOptions startup_options(workspace_layout.get());
  set_startup_options(startup_options, blaze_path, output_dir);
  LoggingInfo logging_info(blaze_path, blaze::GetMillisecondsMonotonic());

  std::optional<DurationMillis> extraction_time_one =
      ExtractData(blaze_path, archive_contents, expected_install_md5,
                  startup_options, &logging_info);
  ASSERT_TRUE(extraction_time_one.has_value());

  std::optional<DurationMillis> extraction_time_two =
      ExtractData(blaze_path, archive_contents, expected_install_md5,
                  startup_options, &logging_info);
  ASSERT_FALSE(extraction_time_two.has_value());
}
}  // namespace blaze
