// 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/strings/escaping.h"
#include "src/main/cpp/blaze.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"));

  std::unique_ptr<blaze_util::IFileMtime> mtime(blaze_util::CreateFileMtime());
  EXPECT_TRUE(mtime->IsUntampered(blaze_util::Path(foo_path)));
  EXPECT_TRUE(mtime->IsUntampered(blaze_util::Path(bar_path)));
  EXPECT_TRUE(mtime->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
