// Copyright 2015 The Chromium OS 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 <err.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

#include <iostream>
#include <limits>

#include "bsdiff/bsdiff.h"
#include "bsdiff/bsdiff_arguments.h"
#include "bsdiff/constants.h"
#include "bsdiff/patch_writer_factory.h"

namespace {

// mmap() the passed |filename| to read-only memory and store in |filesize| the
// size of the file. To release the memory, call munmap with the returned
// pointer and filesize. In case of error returns nullptr.
void* MapFile(const char* filename, size_t* filesize) {
  int fd = open(filename, O_RDONLY);
  if (fd < 0) {
    perror("open()");
    return nullptr;
  }

  struct stat st;
  fstat(fd, &st);
  if (static_cast<uint64_t>(st.st_size) > std::numeric_limits<size_t>::max()) {
    fprintf(stderr, "File too big\n");
    close(fd);
    return nullptr;
  }
  *filesize = st.st_size;

  void* ret = mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (ret == MAP_FAILED) {
    perror("mmap()");
    close(fd);
    return nullptr;
  }
  close(fd);
  return ret;
}

// Generate bsdiff patch from the |old_filename| file to the |new_filename|
// file with options in |arguments|. Store the resulting patch in a new
// |patch_filename| file. Returns 0 on success.
int GenerateBsdiffFromFiles(const char* old_filename,
                            const char* new_filename,
                            const char* patch_filename,
                            const bsdiff::BsdiffArguments& arguments) {
  size_t oldsize;
  uint8_t* old_buf = static_cast<uint8_t*>(MapFile(old_filename, &oldsize));
  if (!old_buf) {
    return 1;
  }

  size_t newsize;
  uint8_t* new_buf = static_cast<uint8_t*>(MapFile(new_filename, &newsize));
  if (!new_buf) {
    munmap(old_buf, oldsize);
    return 1;
  }

  std::unique_ptr<bsdiff::PatchWriterInterface> patch_writer;
  std::vector<uint8_t> raw_data;

  if (arguments.format() == bsdiff::BsdiffFormat::kLegacy) {
    patch_writer = bsdiff::CreateBsdiffPatchWriter(patch_filename);
  } else if (arguments.format() == bsdiff::BsdiffFormat::kBsdf2) {
    patch_writer = bsdiff::CreateBSDF2PatchWriter(patch_filename,
                                                  arguments.compressor_types(),
                                                  arguments.brotli_quality());
  } else if (arguments.format() == bsdiff::BsdiffFormat::kEndsley) {
    patch_writer = bsdiff::CreateEndsleyPatchWriter(
        &raw_data, arguments.compressor_types()[0], arguments.brotli_quality());
  } else {
    std::cerr << "unexpected bsdiff format." << std::endl;
    return 1;
  }

  int ret = bsdiff::bsdiff(old_buf, oldsize, new_buf, newsize,
                           arguments.min_length(), patch_writer.get(), nullptr);

  munmap(old_buf, oldsize);
  munmap(new_buf, newsize);

  if (!ret && arguments.format() == bsdiff::BsdiffFormat::kEndsley) {
    // Store the raw_data on disk.
    FILE* fp = fopen(patch_filename, "wb");
    if (!fp) {
      perror("Opening the patch file");
      return 1;
    }
    if (raw_data.size() != fwrite(raw_data.data(), 1, raw_data.size(), fp)) {
      perror("Writing to the patch file");
      ret = 1;
    }
    fclose(fp);
  }
  return ret;
}

void PrintUsage(const std::string& proc_name) {
  std::cerr << "usage: " << proc_name
            << " [options] oldfile newfile patchfile\n";
  std::cerr << "  --format <legacy|bsdiff40|bsdf2|endsley>  The format of the"
               " bsdiff patch.\n"
            << "  --minlen LEN                       The minimum match length "
               "required to consider a match in the algorithm.\n"
            << "  --type <bz2|brotli|nocompression>  The algorithm to compress "
               "the patch, bsdf2 format only. Multiple supported compressors "
               "should be split by ':', e.g. bz2:brotli.\n"
            << "  --brotli_quality                   Quality of the brotli "
               "compressor.\n";
}

}  // namespace

int main(int argc, char* argv[]) {
  bsdiff::BsdiffArguments arguments;

  if (!arguments.ParseCommandLine(argc, argv)) {
    PrintUsage(argv[0]);
    return 1;
  }

  // The optind will be updated in ParseCommandLine to parse the options; and
  // we expect the rest of the arguments to be oldfile, newfile, patchfile.
  if (!arguments.IsValid() || argc - optind != 3) {
    PrintUsage(argv[0]);
    return 1;
  }

  return GenerateBsdiffFromFiles(argv[optind], argv[optind + 1],
                                 argv[optind + 2], arguments);
}
