// Copyright 2017, 2018 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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <string>
#include <thread>
#include <vector>

#include <fbl/alloc_checker.h>
#include <fbl/unique_fd.h>

#include "src/lib/digest/digest.h"
#include "src/lib/digest/merkle-tree.h"

namespace {

using digest::Digest;
using digest::MerkleTreeCreator;

struct FileEntry {
  std::string filename;
  char digest[digest::kSha256HexLength + 1]{};
};

void usage(char** argv) {
  fprintf(stderr, "Usage: %s [-o OUTPUT | -m MANIFEST] FILE...\n", argv[0]);
  fprintf(stderr,
          "\n\
With -o, OUTPUT gets the same format normally written to stdout: HASH - FILE.\n\
With -m, MANIFEST gets \"manifest file\" format: HASH=FILE.\n\
Any argument may be \"@RSPFILE\" to be replaced with the contents of RSPFILE.\n\
");
  exit(1);
}

int handle_argument(char** argv, const char* arg, std::vector<FileEntry>* entries) {
  if (arg[0] == '@') {
    FILE* rspfile = fopen(&arg[1], "r");
    if (!rspfile) {
      perror(&arg[1]);
      return 1;
    }
    while (!feof(rspfile) && !ferror(rspfile)) {
      // 2018 macOS hasn't caught up with C99 yet, so can't use %ms here.
      char filename[4096];
      if (fscanf(rspfile, " %4095s", filename) == 1) {
        handle_argument(argv, filename, entries);
      }
    }
    int result = ferror(rspfile);
    if (result) {
      perror(&arg[1]);
    }
    fclose(rspfile);
    return result;
  } else {
    entries->push_back({arg});
    return 0;
  }
}

void handle_entry(FileEntry* entry) {
  fbl::unique_fd fd{open(entry->filename.c_str(), O_RDONLY)};
  if (!fd) {
    perror(entry->filename.c_str());
    exit(1);
  }

  struct stat info;
  if (fstat(fd.get(), &info) < 0) {
    perror("fstat");
    exit(1);
  }
  if (!S_ISREG(info.st_mode)) {
    return;
  }

  // Buffer one intermediate node's worth at a time.
  void* data = nullptr;
  if (info.st_size != 0) {
    data = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd.get(), 0);
  }
  if (info.st_size != 0 && data == MAP_FAILED) {
    perror("mmap");
    exit(1);
  }
  std::unique_ptr<uint8_t[]> tree;
  size_t len;
  Digest digest;
  zx_status_t rc = MerkleTreeCreator::Create(data, info.st_size, &tree, &len, &digest);
  if (info.st_size != 0 && munmap(data, info.st_size) != 0) {
    perror("munmap");
    exit(1);
  }
  if (rc != ZX_OK) {
    fprintf(stderr, "%s: Merkle tree creation failed: %d\n", entry->filename.c_str(), rc);
    exit(1);
  }
  snprintf(entry->digest, sizeof(entry->digest), "%s", digest.ToString().c_str());
}

}  // namespace

int main(int argc, char** argv) {
  FILE* outf = stdout;
  if (argc < 2) {
    usage(argv);
  }

  int argi = 1;
  bool manifest = !strcmp(argv[1], "-m");
  if (manifest || !strcmp(argv[1], "-o")) {
    if (argc < 4) {
      usage(argv);
    }
    argi = 3;
    outf = fopen(argv[2], "w");
    if (!outf) {
      perror(argv[2]);
      return 1;
    }
  }

  std::vector<FileEntry> entries;
  for (; argi < argc; ++argi) {
    if (handle_argument(argv, argv[argi], &entries))
      return 1;
  }

  std::vector<std::thread> threads;
  std::mutex mtx;
  size_t next_entry = 0;
  size_t n_threads = std::thread::hardware_concurrency();
  if (!n_threads) {
    n_threads = 4;
  }
  if (n_threads > entries.size()) {
    n_threads = entries.size();
  }
  for (size_t i = n_threads; i > 0; --i) {
    threads.push_back(std::thread([&] {
      while (true) {
        mtx.lock();
        auto j = next_entry++;
        mtx.unlock();
        if (j >= entries.size()) {
          return;
        }
        handle_entry(&entries[j]);
      }
    }));
  }
  for (unsigned i = 0; i < threads.size(); ++i) {
    threads[i].join();
  }

  for (const auto& entry : entries) {
    fprintf(outf, "%s%s%s\n", entry.digest, manifest ? "=" : " - ", entry.filename.c_str());
  }

  return 0;
}
