// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#include "garnet/lib/far/archive_reader.h"
#include "garnet/lib/far/archive_writer.h"
#include "garnet/lib/far/manifest.h"
#include "src/lib/fxl/command_line.h"
#include "src/lib/files/unique_fd.h"

namespace archive {

// Commands
constexpr fxl::StringView kCat = "cat";
constexpr fxl::StringView kCreate = "create";
constexpr fxl::StringView kList = "list";
constexpr fxl::StringView kExtract = "extract";
constexpr fxl::StringView kExtractFile = "extract-file";

constexpr fxl::StringView kKnownCommands =
    "create, list, cat, extract, or extract-file";

// Options
constexpr fxl::StringView kArchive = "archive";
constexpr fxl::StringView kManifest = "manifest";
constexpr fxl::StringView kFile = "file";
constexpr fxl::StringView kOutput = "output";

constexpr fxl::StringView kCatUsage = "cat --archive=<archive> --file=<path> ";
constexpr fxl::StringView kCreateUsage =
    "create --archive=<archive> --manifest=<manifest>";
constexpr fxl::StringView kListUsage = "list --archive=<archive>";
constexpr fxl::StringView kExtractUsage =
    "extract --archive=<archive> --output=<path>";
constexpr fxl::StringView kExtractFileUsage =
    "extract-file --archive=<archive> --file=<path> --output=<path>";

bool GetOptionValue(const fxl::CommandLine& command_line,
                    fxl::StringView option, fxl::StringView usage,
                    std::string* value) {
  if (!command_line.GetOptionValue(option, value)) {
    fprintf(stderr,
            "error: Missing --%s argument.\n"
            "Usage: far %s\n",
            option.data(), usage.data());
    return false;
  }
  return true;
}

int Create(const fxl::CommandLine& command_line) {
  std::string archive_path;
  if (!GetOptionValue(command_line, kArchive, kCreateUsage, &archive_path))
    return -1;

  std::vector<fxl::StringView> manifest_paths =
      command_line.GetOptionValues(kManifest);
  if (manifest_paths.empty())
    return -1;

  archive::ArchiveWriter writer;
  for (const auto& manifest_path : manifest_paths) {
    if (!archive::ReadManifest(manifest_path, &writer))
      return -1;
  }
  fxl::UniqueFD fd(open(archive_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
                        S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
  if (!fd.is_valid())
    return -1;
  return writer.Write(fd.get()) ? 0 : -1;
}

int List(const fxl::CommandLine& command_line) {
  std::string archive_path;
  if (!GetOptionValue(command_line, kArchive, kListUsage, &archive_path))
    return -1;

  fxl::UniqueFD fd(open(archive_path.c_str(), O_RDONLY));
  if (!fd.is_valid())
    return -1;
  archive::ArchiveReader reader(std::move(fd));
  if (!reader.Read())
    return -1;
  reader.ListPaths([](fxl::StringView string) {
    printf("%.*s\n", static_cast<int>(string.size()), string.data());
  });
  return 0;
}

int Extract(const fxl::CommandLine& command_line) {
  std::string archive_path;
  if (!GetOptionValue(command_line, kArchive, kExtractUsage, &archive_path))
    return -1;

  std::string output_dir;
  if (!GetOptionValue(command_line, kOutput, kExtractUsage, &output_dir))
    return -1;

  fxl::UniqueFD fd(open(archive_path.c_str(), O_RDONLY));
  if (!fd.is_valid())
    return -1;
  archive::ArchiveReader reader(std::move(fd));
  if (!reader.Read())
    return -1;
  if (!reader.Extract(output_dir))
    return -1;
  return 0;
}

int ExtractFile(const fxl::CommandLine& command_line) {
  std::string archive_path;
  if (!GetOptionValue(command_line, kArchive, kExtractFileUsage, &archive_path))
    return -1;

  std::string file_path;
  if (!GetOptionValue(command_line, kFile, kExtractFileUsage, &file_path))
    return -1;

  std::string output_path;
  if (!GetOptionValue(command_line, kOutput, kExtractFileUsage, &output_path))
    return -1;

  fxl::UniqueFD fd(open(archive_path.c_str(), O_RDONLY));
  if (!fd.is_valid())
    return -1;
  archive::ArchiveReader reader(std::move(fd));
  if (!reader.Read())
    return -1;
  if (!reader.ExtractFile(file_path, output_path.c_str()))
    return -1;
  return 0;
}

int Cat(const fxl::CommandLine& command_line) {
  std::string archive_path;
  if (!GetOptionValue(command_line, kArchive, kCatUsage, &archive_path))
    return -1;

  std::string file_path;
  if (!GetOptionValue(command_line, kFile, kCatUsage, &file_path))
    return -1;

  fxl::UniqueFD fd(open(archive_path.c_str(), O_RDONLY));
  if (!fd.is_valid())
    return -1;
  archive::ArchiveReader reader(std::move(fd));
  if (!reader.Read())
    return -1;
  if (!reader.CopyFile(file_path, STDOUT_FILENO))
    return -1;
  return 0;
}

int RunCommand(std::string command, const fxl::CommandLine& command_line) {
  if (command == kCreate) {
    return archive::Create(command_line);
  } else if (command == kList) {
    return archive::List(command_line);
  } else if (command == kExtract) {
    return archive::Extract(command_line);
  } else if (command == kExtractFile) {
    return archive::ExtractFile(command_line);
  } else if (command == kCat) {
    return archive::Cat(command_line);
  } else {
    fprintf(stderr,
            "error: Unknown command: %s\n"
            "Known commands: %s.\n",
            command.c_str(), kKnownCommands.data());
    return -1;
  }
}

}  // namespace archive

int main(int argc, char** argv) {
  if (argc < 2) {
    fprintf(stderr,
            "error: Missing command.\n"
            "Usage: far <command> ...\n"
            "  where <command> is %s.\n",
            archive::kKnownCommands.data());
    return -1;
  }

  return archive::RunCommand(argv[1],
                             fxl::CommandLineFromArgcArgv(argc - 1, argv + 1));
}
