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


#include <sys/stat.h>

#include <cstddef>
#include <iostream>
#include <random>
#include <sstream>

#include "archive_reader.h"
#include "archive_writer.h"
#include "base/strings/string_split.h"
#include "crc32_hasher.h"
#include "zst_compressor.h"
#include "zst_decompressor.h"

void PrintUsageInfo(std::string program_name) {
  std::cerr << "Usage: " << program_name << " [hash | archive | extract | pipe]"
            << std::endl;
}

void PrintUsageInfoHash(std::string program_name) {
  std::cerr << "Usage: " << program_name << " hash '" << kFilePathDelimiter
            << "'-separated-file-paths" << std::endl;
  std::cerr << "E.g.: " << program_name << " hash path1" << kFilePathDelimiter
            << "path2" << std::endl;
}

void PrintUsageInfoCompress(std::string program_name) {
  std::cerr << "Usage: " << program_name
            << " compress destination-file-path uncompressed-content"
            << std::endl;
  std::cerr << "E.g.: " << program_name
            << " compress /path/to/compressed/content abcdefg" << std::endl;
}

void PrintUsageInfoArchive(std::string program_name) {
  std::cerr << "Usage: " << program_name
            << " archive [archive-path | -] archive-members-file-path"
            << std::endl;
  std::cerr << "E.g.: " << program_name
            << " archive /path/to/archive /path/to/archive/members/file"
            << std::endl;
}

void PrintUsageInfoExtract(std::string program_name) {
  std::cerr << "Usage: " << program_name << " extract [archive-path | -]"
            << std::endl;
  std::cerr << "E.g.: " << program_name
            << " archive - /path/to/archive/members/file | " << program_name
            << " extract -" << std::endl;
}

void PrintUsageInfoPipe(std::string program_name) {
  std::cerr << "Usage: " << program_name << " pipe named-pipe-path"
            << std::endl;
  std::cerr << "E.g.: " << program_name << " pipe /path/to/named/pipe"
            << std::endl;
}

// The hash command is given a list of kFilePathDelimiter-separated file paths
// which are gzipped and base64-encoded, and it outputs a crc32 hash for each
// file in the list, in the same order as the input list. If a file does not
// exist, outputs a blank line for it.
int DoHash(const std::vector<std::string>& argv) {
  if (argv.size() != 3) {
    PrintUsageInfoHash(argv[0]);
    return 1;
  }

  Crc32Hasher hasher;
  std::vector<std::string> files = hasher.ParseFileList(argv[2]);

  for (const auto& file : files) {
    std::optional<uint32_t> hash = hasher.HashFile(file);
    if (!hash.has_value()) {
      std::cout << "\n";  // Blank line for missing file.
    } else {
      std::cout << std::hex << hash.value() << "\n";
    }
  }
  return 0;
}

// The compress command is given a string that needs to be compressed.
// It compresses the string via zst and saves the result to the specified file.
int DoCompress(const std::vector<std::string>& argv) {
  if (argv.size() != 4) {
    PrintUsageInfoCompress(argv[0]);
    return 1;
  }

  std::string destination_file_path = argv[2];
  std::ofstream output_file_stream;
  output_file_stream.open(destination_file_path,
                          std::ios::binary | std::ios::trunc);
  if (output_file_stream.fail()) {
    std::cerr << "Failed to open the destination file at "
              << destination_file_path << std::endl;
    return 1;
  }

  ZstCompressor compressor(output_file_stream, 3);
  std::string uncompressed_string = argv[3];
  ZstCompressor::UncompressedContent uncompressed_content;
  uncompressed_content.buffer = uncompressed_string.data();
  uncompressed_content.size = uncompressed_string.size();
  compressor.CompressStreaming(uncompressed_content, true);
  return 0;
}

// The archive command creates a zst-compressed archive file. It is given a text
// file that contains the paths to the files that should be included in archive.
// It then creates an archive from these files and compresses the archive via
// zstd. The archive is in a custom file format and can be extracted using the
// extract command below.
int DoArchive(const std::vector<std::string>& argv) {
  if (argv.size() != 4) {
    PrintUsageInfoArchive(argv[0]);
    return 1;
  }

  // If the user passes - as the output archive, then we write to standard
  // output. Otherwise, we write to a file.
  std::string archive_path = argv[2];
  std::ofstream output_file_stream;
  std::ostream& output_stream =
      archive_path == "-" ? std::cout : output_file_stream;
  if (archive_path != "-") {
    output_file_stream.open(archive_path, std::ios::binary | std::ios::trunc);
    if (output_file_stream.fail()) {
      std::cerr << "Failed to open the archive at " << archive_path
                << std::endl;
      return 1;
    }
  }

  // The archive members file contains two lines for each member: the first
  // line is the file path of the member in the host machine, the second line
  // is the file path of the member in the archive.
  std::string archive_members_file_path = argv[3];
  std::ifstream archive_members_file(archive_members_file_path);
  std::vector<ArchiveWriter::ArchiveMember> archive_members;
  while (true) {
    ArchiveWriter::ArchiveMember member;
    if (!std::getline(archive_members_file, member.file_path_in_host)) {
      break;
    }
    if (!std::getline(archive_members_file, member.file_path_in_archive)) {
      std::cerr << "The archive members file contains an odd number of lines!"
                << std::endl;
      return 1;
    }
    archive_members.push_back(member);
  }

  // Now we start creating the archive: first ask the archive writer to create
  // a portion of the uncompressed archive, and then ask the zst compressor to
  // compress it and write to the output stream, and then ask the archive
  // writer to create the next portion of the uncompressed archive and repeat.
  ArchiveWriter writer(std::move(archive_members));
  ZstCompressor compressor(output_stream, 3);
  size_t archive_buffer_size = compressor.GetRecommendedInputBufferSize();
  std::unique_ptr<char[]> archive_buffer =
      std::make_unique<char[]>(archive_buffer_size);
  ZstCompressor::UncompressedContent uncompressed_content;
  while (true) {
    size_t num_bytes_written = writer.CreateArchiveStreaming(
        archive_buffer.get(), archive_buffer_size);
    uncompressed_content.buffer = archive_buffer.get();
    uncompressed_content.size = num_bytes_written;
    bool last_chunk = (num_bytes_written < archive_buffer_size);
    compressor.CompressStreaming(uncompressed_content, last_chunk);
    if (last_chunk) {
      break;
    }
  }
  return 0;
}

// The extract command is given a zst-compressed archive file, and it
// decompresses the file using zstd and extracts the files from the archive.
// It does so in a streaming way (i.e. it reads a portion of the input file and
// extracts it, and then read the next portion of input file and extracts it).
// The input file can be created by the archive command above.
int DoExtract(const std::vector<std::string>& argv) {
  if (argv.size() != 3) {
    PrintUsageInfoExtract(argv[0]);
    return 1;
  }

  // If the user passes - as the input archive, then we read from standard
  // input. Otherwise, we read from a file.
  std::string archive_path = argv[2];
  std::ifstream input_file_stream;
  std::istream& input_stream =
      archive_path == "-" ? std::cin : input_file_stream;
  if (archive_path != "-") {
    input_file_stream.open(archive_path, std::ios::binary);
    if (input_file_stream.fail()) {
      std::cerr << "Failed to open the archive at " << archive_path
                << std::endl;
      return 1;
    }
  }

  // We extract the input archive in a streaming way: first ask the zst
  // decompressor to read a portion of the input and decompress it, and then
  // ask the archive reader to extract the decompressed archive, and then ask
  // the zst decompresssor to read the next portion of the input and repeat.
  ZstDecompressor decompressor(input_stream);
  ArchiveReader reader;
  ZstDecompressor::DecompressedContent decompressed_content;
  while (true) {
    if (decompressor.DecompressStreaming(&decompressed_content)) {
      std::cerr << "Archive reader has not reached the end of the input file "
                   "but there is already no data left. This likely means the "
                   "input data is truncated."
                << std::endl;
      return 1;
    }
    if (reader.ExtractArchiveStreaming(decompressed_content.buffer,
                                       decompressed_content.size)) {
      break;
    }
  }
  return 0;
}

// The pipe command is given a path, and it creates a named pipe at that path
// via a mkfifo() system call.
int DoPipe(const std::vector<std::string>& argv) {
  if (argv.size() != 3) {
    PrintUsageInfoPipe(argv[0]);
    return 1;
  }

  std::string named_pipe_path = argv[2];
  int result = mkfifo(named_pipe_path.c_str(), 0777);
  if (result != 0) {
    std::cerr << "Failed to call mkfifo(): " << strerror(errno) << std::endl;
    return 1;
  }
  return 0;
}

// Given the path to a response file, process the response file and return the
// command line arguments that it contains as a vector of strings.
std::vector<std::string> HandleResponseFile(
    const std::string& response_file_path) {
  std::string response_file_content;
  if (response_file_path.length() >= 4 &&
      response_file_path.substr(response_file_path.length() - 4) == ".zst") {
    // If the path to the response file ends in .zst, then decompress the
    // content of the response file via zst.
    std::ifstream input_file_stream;
    input_file_stream.open(response_file_path, std::ios::binary);
    if (input_file_stream.fail()) {
      std::cerr << "Failed to open the input response file at "
                << response_file_path << std::endl;
      exit(1);
    }
    ZstDecompressor decompressor(input_file_stream);
    ZstDecompressor::DecompressedContent decompressed_content;
    std::stringstream decompressed_string_stream;
    while (true) {
      if (decompressor.DecompressStreaming(&decompressed_content)) {
        break;
      }
      decompressed_string_stream.write(decompressed_content.buffer,
                                       decompressed_content.size);
    }
    response_file_content = decompressed_string_stream.str();
  } else {
    // If the path to the response file does not end in .zst, then read the
    // entire content of the response file.
    std::ifstream input_file_stream;
    input_file_stream.open(response_file_path);
    if (input_file_stream.fail()) {
      std::cerr << "Failed to open the input response file at "
                << response_file_path << std::endl;
      exit(1);
    }
    std::stringstream string_stream;
    string_stream << input_file_stream.rdbuf();
    response_file_content = string_stream.str();
  }
  // Each line in the response file is treated as a separate command line
  // argument.
  return SplitString(response_file_content, "\n", base::KEEP_WHITESPACE,
                     base::SPLIT_WANT_NONEMPTY);
}

int main(int argc, const char* argv[]) {
  // Pre-process the command line arguments and expand all the response files
  // (a response file is identified by the @ symbol).
  std::vector<std::string> processed_argv;
  for (int i = 0; i < argc; ++i) {
    std::string arg = argv[i];
    if (arg.length() >= 1 && arg[0] == '@') {
      std::string response_file_path = arg.substr(1);
      std::vector<std::string> response_file_args =
          HandleResponseFile(response_file_path);
      processed_argv.insert(processed_argv.end(), response_file_args.begin(),
                            response_file_args.end());
    } else {
      processed_argv.push_back(arg);
    }
  }

  if (processed_argv.size() < 2) {
    PrintUsageInfo(processed_argv[0]);
    return 1;
  }

  std::string command = processed_argv[1];
  if (command == "hash") {
    return DoHash(processed_argv);
  } else if (command == "compress") {
    return DoCompress(processed_argv);
  } else if (command == "archive") {
    return DoArchive(processed_argv);
  } else if (command == "extract") {
    return DoExtract(processed_argv);
  } else if (command == "pipe") {
    return DoPipe(processed_argv);
  } else {
    PrintUsageInfo(processed_argv[0]);
    return 1;
  }
}
