// Copyright 2024 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <optional>
#include <string>

#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/hash/md5.h>
#include <base/logging.h>
#include <brillo/flag_helper.h>
#include <brillo/proto_file_io.h>

#include "patchmaker/directory_util.h"
#include "patchmaker/file_util.h"
#include "patchmaker/managed_directory.h"

namespace {

bool EncodeDirectory(const base::FilePath& src_path,
                     const base::FilePath& dest_path,
                     const std::string& input_manifest_str,
                     const std::string& immutable_path_str,
                     const double cluster_ratio) {
  ManagedDirectory managed_dir;

  if (!managed_dir.CreateNew(dest_path,
                             input_manifest_str.empty()
                                 ? std::optional<base::FilePath>{}
                                 : base::FilePath(input_manifest_str))) {
    LOG(ERROR) << "Failed to initialize ManagedDirectory";
    return false;
  }

  std::vector<base::FilePath> immutable_paths;
  util::ParseDelimitedFilePaths(immutable_path_str, &immutable_paths);
  for (const auto& path : immutable_paths) {
    if (!base::PathExists(path)) {
      LOG(ERROR) << "Path requesting immutability doesn't exist: " << path;
      return false;
    }
  }

  if (!managed_dir.Encode(src_path, dest_path, immutable_paths,
                          cluster_ratio)) {
    LOG(ERROR) << "Failed to encode source path " << src_path;
    return false;
  }

  return true;
}

// Target path could be a single file or sub-directory within a managed
// directory
bool DecodeDirectory(const base::FilePath& target_path,
                     const base::FilePath& dest_path) {
  ManagedDirectory managed_dir;

  if (!managed_dir.CreateFromExisting(target_path)) {
    LOG(ERROR) << "Failed to initialize ManagedDirectory";
    return false;
  }
  if (!managed_dir.Decode(target_path, dest_path)) {
    LOG(ERROR) << "Failed to decode target path " << target_path;
    return false;
  }

  return true;
}

bool EndToEndTest(const base::FilePath& src_path) {
  // Take a directory as input, encode it, and then reconstruct it,
  // ensuring that the reconstructed contents are identical to the
  // originals.

  // Step 1 - Create temp directories for encode and decode
  base::ScopedTempDir tmp_encode, tmp_decode;
  if (!tmp_encode.CreateUniqueTempDir() || !tmp_decode.CreateUniqueTempDir()) {
    LOG(ERROR) << "Failed to create temp directories for testing";
    return false;
  }

  // Step 2 - Call EncodeDirectory from src_path to tmp_encode
  LOG(INFO) << "Encoding into " << tmp_encode.GetPath();
  if (!EncodeDirectory(src_path, tmp_encode.GetPath(), "", "", kClusterRatio)) {
    LOG(ERROR) << "Encode step failed";
    return false;
  }

  // Step 3 - Call DecodeDirectory from tmp_encode to tmp_decode
  LOG(INFO) << "Decoding into " << tmp_decode.GetPath();
  if (!DecodeDirectory(tmp_encode.GetPath(), tmp_decode.GetPath())) {
    LOG(ERROR) << "Decode step failed";
    return false;
  }

  // Step 4 - Ensure src_path and tmp_decode paths have identical contents
  if (!util::DirectoriesAreEqual(src_path, tmp_decode.GetPath())) {
    LOG(ERROR) << "Failed to validate equality after decode";
    return false;
  }

  LOG(INFO) << "Src size " << ComputeDirectorySize(src_path)
            << ", Encoded size " << ComputeDirectorySize(tmp_encode.GetPath());

  LOG(INFO) << "All validation checks passed :)";
  return true;
}

}  // namespace

int main(int argc, char* argv[]) {
  DEFINE_bool(encode, false, "Generate patches to replace original files");
  DEFINE_bool(decode, false, "Reconstruct original files from patches");
  DEFINE_bool(end_to_end, false, "Encode, decode, and validate contents");

  DEFINE_string(src_path, "", "Source path for operation");
  DEFINE_string(dest_path, "", "Destination path for encode operation");

  DEFINE_string(input_manifest, "", "Optional: Input manifest for operation");
  DEFINE_string(immutable_paths, "",
                "Optional: Colon (':') separated list of immutable files or "
                "directories that must be left intact.");
  DEFINE_double(cluster_ratio, kClusterRatio,
                "Size ratio for clustering files (e.g., 1.2 for 20%)");

  brillo::FlagHelper::Init(argc, argv, "Patch utility for binary storage.");

  int num_operations = FLAGS_encode + FLAGS_decode + FLAGS_end_to_end;
  if (num_operations != 1) {
    LOG(ERROR) << "Expected one of --encode / --decode / --end_to_end";
    return EXIT_FAILURE;
  }

  if (FLAGS_src_path.empty()) {
    LOG(ERROR) << "--src_path is required";
    return EXIT_FAILURE;
  }

  if (FLAGS_end_to_end) {
    return EndToEndTest(base::FilePath(FLAGS_src_path)) ? EXIT_SUCCESS
                                                        : EXIT_FAILURE;
  }

  if (FLAGS_dest_path.empty()) {
    LOG(ERROR) << "--dest_path is required";
    return EXIT_FAILURE;
  }

  if (FLAGS_encode) {
    return EncodeDirectory(
               base::FilePath(FLAGS_src_path), base::FilePath(FLAGS_dest_path),
               FLAGS_input_manifest, FLAGS_immutable_paths, FLAGS_cluster_ratio)
               ? EXIT_SUCCESS
               : EXIT_FAILURE;
  }

  if (FLAGS_decode) {
    return DecodeDirectory(base::FilePath(FLAGS_src_path),
                           base::FilePath(FLAGS_dest_path))
               ? EXIT_SUCCESS
               : EXIT_FAILURE;
  }

  NOTREACHED();
}
