// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// Zip / Unzip file using ijar zip implementation.
//
// Note that this Zip implementation intentionally don't compute CRC-32
// because it is useless computation for jar because Java doesn't care.
// CRC-32 of all files in the zip file will be set to 0.
//

#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <memory>
#include <set>
#include <string>

#include "third_party/ijar/platform_utils.h"
#include "third_party/ijar/zip.h"

namespace devtools_ijar {

//
// A ZipExtractorProcessor that extract files in the ZIP file.
//
class UnzipProcessor : public ZipExtractorProcessor {
 public:
  // Create a processor who will extract the given files (or all files if NULL)
  // into output_root if "extract" is set to true and will print the list of
  // files and their unix modes if "verbose" is set to true.
  UnzipProcessor(const char *output_root, char **files, bool verbose,
                 bool extract, bool flatten)
      : output_root_(output_root),
        verbose_(verbose),
        extract_(extract),
        flatten_(flatten) {
    if (files != NULL) {
      for (int i = 0; files[i] != NULL; i++) {
        file_names.insert(std::string(files[i]));
      }
    }
  }

  virtual ~UnzipProcessor() {}

  virtual void Process(const char* filename, const u4 attr,
                       const u1* data, const size_t size);
  virtual bool Accept(const char* filename, const u4 attr) {
    // All entry files are accepted by default.
    if (file_names.empty()) {
      return true;
    } else {
      // If users have specified file entries, only accept those files.
      return file_names.count(std::string(filename)) == 1;
    }
  }

 private:
  const char *output_root_;
  const bool verbose_;
  const bool extract_;
  const bool flatten_;
  std::set<std::string> file_names;
};

// Concatene 2 path, path1 and path2, using / as a directory separator and
// putting the result in "out". "size" specify the size of the output buffer. If
// the result would overflow the output buffer, print an error message and
// return false.
bool concat_path(char *out, const size_t size, const char *path1,
                 const char *path2) {
  int len1 = strlen(path1);
  size_t l = len1;
  strncpy(out, path1, size - 1);
  out[size - 1] = 0;
  if (l < size - 1 && path1[len1] != '/' && path2[0] != '/') {
    out[l] = '/';
    l++;
    out[l] = 0;
  }
  if (l >= size - 1) {
    fprintf(stderr, "paths too long to concat: %s + %s", path1, path2);
    return false;
  }
  strncat(out, path2, size - 1 - l);
  return true;
}

void UnzipProcessor::Process(const char* filename, const u4 attr,
                             const u1* data, const size_t size) {
  mode_t perm = zipattr_to_perm(attr);
  bool isdir = zipattr_is_dir(attr);
  const char *output_file_name = filename;
  if (attr == 0) {
    // Fallback when the external attribute is not set.
    isdir = filename[strlen(filename)-1] == '/';
    perm = 0777;
  }

  if (flatten_) {
    if (isdir) {
      return;
    }
    const char *p = strrchr(filename, '/');
    if (p != NULL) {
      output_file_name = p + 1;
    }
  }

  if (verbose_) {
    printf("%c %o %s\n", isdir ? 'd' : 'f', perm, output_file_name);
  }
  if (extract_) {
    char path[PATH_MAX];
    if (!concat_path(path, sizeof(path), output_root_, output_file_name) ||
        !make_dirs(path, perm) ||
        (!isdir && !write_file(path, perm, data, size))) {
      abort();
    }
  }
}

// Get the basename of path and store it in output. output_size
// is the size of the output buffer.
void basename(const char *path, char *output, size_t output_size) {
  const char *pointer = strrchr(path, '/');
  if (pointer == NULL) {
    pointer = path;
  } else {
    pointer++;  // Skip the leading slash.
  }
  strncpy(output, pointer, output_size - 1);
  output[output_size - 1] = 0;
}

// Execute the extraction (or just listing if just v is provided)
int extract(char *zipfile, char *exdir, char **files, bool verbose,
            bool extract, bool flatten) {
  std::string cwd = get_cwd();
  if (cwd.empty()) {
    return -1;
  }

  char output_root[PATH_MAX + 1];
  if (exdir != NULL) {
    if (!concat_path(output_root, sizeof(output_root), cwd.c_str(), exdir)) {
      return -1;
    }
  } else if (cwd.length() >= sizeof(output_root)) {
    fprintf(stderr, "current working directory path too long");
    return -1;
  } else {
    memcpy(output_root, cwd.c_str(), cwd.length() + 1);
  }

  UnzipProcessor processor(output_root, files, verbose, extract, flatten);
  std::unique_ptr<ZipExtractor> extractor(ZipExtractor::Create(zipfile,
                                                               &processor));
  if (extractor == NULL) {
    fprintf(stderr, "Unable to open zip file %s: %s.\n", zipfile,
            strerror(errno));
    return -1;
  }

  if (extractor->ProcessAll() < 0) {
    fprintf(stderr, "%s.\n", extractor->GetError());
    return -1;
  }
  return 0;
}

// add a file to the zip
int add_file(std::unique_ptr<ZipBuilder> const &builder, char *file,
             char *zip_path, bool flatten, bool verbose, bool compress) {
  Stat file_stat = {0, 0666, false};
  if (file != NULL) {
    if (!stat_file(file, &file_stat)) {
      fprintf(stderr, "Cannot stat file %s: %s\n", file, strerror(errno));
      return -1;
    }
  }
  char *final_path = zip_path != NULL ? zip_path : file;

  bool isdir = file_stat.is_directory;

  if (flatten && isdir) {
    return 0;
  }

  // Compute the path, flattening it if requested
  char path[PATH_MAX];
  size_t len = strlen(final_path);
  if (len > PATH_MAX) {
    fprintf(stderr, "Path too long: %s.\n", final_path);
    return -1;
  }
  if (flatten) {
    basename(final_path, path, PATH_MAX);
  } else {
    strncpy(path, final_path, PATH_MAX);
    path[PATH_MAX - 1] = 0;
    if (isdir && len < PATH_MAX - 1) {
      // Add the trailing slash for folders
      path[len] = '/';
      path[len + 1] = 0;
    }
  }

  if (verbose) {
    mode_t perm = file_stat.file_mode & 0777;
    printf("%c %o %s\n", isdir ? 'd' : 'f', perm, path);
  }

  u1 *buffer = builder->NewFile(path, stat_to_zipattr(file_stat));
  if (isdir || file_stat.total_size == 0) {
    builder->FinishFile(0);
  } else {
    if (!read_file(file, buffer, file_stat.total_size)) {
      return -1;
    }
    builder->FinishFile(file_stat.total_size, compress, true);
  }
  return 0;
}

// Read a list of files separated by newlines. The resulting array can be
// freed using the free method.
char **read_filelist(char *filename) {
  Stat file_stat;
  if (!stat_file(filename, &file_stat)) {
    fprintf(stderr, "Cannot stat file %s: %s\n", filename, strerror(errno));
    return NULL;
  }

  char *data = static_cast<char *>(malloc(file_stat.total_size));
  if (!read_file(filename, data, file_stat.total_size)) {
    return NULL;
  }

  int nb_entries = 1;
  for (u8 i = 0; i < file_stat.total_size; i++) {
    if (data[i] == '\n') {
      nb_entries++;
    }
    if (nb_entries == INT_MAX) {
      fprintf(stderr, "too many input files");
      return NULL;
    }
  }

  size_t sizeof_array = sizeof(char *) * (nb_entries + 1);
  void *result = malloc(sizeof_array + file_stat.total_size + 1);
  // copy the content
  char **filelist = static_cast<char **>(result);
  char *content = static_cast<char *>(result) + sizeof_array;
  memcpy(content, data, file_stat.total_size);
  content[file_stat.total_size] = '\0';
  free(data);
  // Create the corresponding array
  int j = 1;
  filelist[0] = content;
  for (u8 i = 0; i < file_stat.total_size; i++) {
    if (content[i] == '\n') {
      content[i] = 0;
      if (i + 1 < file_stat.total_size) {
        filelist[j] = content + i + 1;
        j++;
      }
    }
  }
  filelist[j] = NULL;
  return filelist;
}

// return real paths of the files
char **parse_filelist(char *zipfile, char **file_entries, int nb_entries,
                      bool flatten) {
  // no need to free since the path lists should live until the end of the
  // program
  char **files = static_cast<char **>(malloc(sizeof(char *) * nb_entries));
  char **zip_paths = file_entries;
  for (int i = 0; i < nb_entries; i++) {
    char *p_eq = strchr(file_entries[i], '=');
    if (p_eq != NULL) {
      if (flatten) {
        fprintf(stderr, "Unable to create zip file %s: %s.\n", zipfile,
                "= can't be used with flatten");
        free(files);
        return NULL;
      }
      if (p_eq == file_entries[i]) {
        fprintf(stderr, "Unable to create zip file %s: %s.\n", zipfile,
                "A zip path should be given before =");
        free(files);
        return NULL;
      }
      *p_eq = '\0';
      files[i] = p_eq + 1;
      if (files[i][0] == '\0') {
        files[i] = NULL;
      }
    } else {
      files[i] = file_entries[i];
      zip_paths[i] = NULL;
    }
  }
  return files;
}

// Execute the create operation
int create(char *zipfile, char **file_entries, bool flatten, bool verbose,
           bool compress) {
  int nb_entries = 0;
  while (file_entries[nb_entries] != NULL) {
    nb_entries++;
  }
  char **zip_paths = file_entries;
  char **files = parse_filelist(zipfile, file_entries, nb_entries, flatten);
  if (files == NULL) {
    return -1;
  }

  u8 size = ZipBuilder::EstimateSize(files, zip_paths, nb_entries);
  if (size == 0) {
    return -1;
  }
  std::unique_ptr<ZipBuilder> builder(ZipBuilder::Create(zipfile, size));
  if (builder == NULL) {
    fprintf(stderr, "Unable to create zip file %s: %s.\n",
            zipfile, strerror(errno));
    return -1;
  }

  for (int i = 0; i < nb_entries; i++) {
    if (add_file(builder, files[i], zip_paths[i], flatten, verbose, compress) <
        0) {
      return -1;
    }
  }
  if (builder->Finish() < 0) {
    fprintf(stderr, "%s\n", builder->GetError());
    return -1;
  }
  return 0;
}

}  // namespace devtools_ijar

//
// main method
//
static void usage(char *progname) {
  fprintf(stderr,
          "Usage: %s [vxc[fC]] x.zip [-d exdir] [[zip_path1=]file1 ... "
          "[zip_pathn=]filen]\n",
          progname);
  fprintf(stderr, "  v verbose - list all file in x.zip\n");
  fprintf(stderr,
          "  x extract - extract files in x.zip to current directory, or "
          "    an optional directory relative to the current directory "
          "    specified through -d option\n");
  fprintf(stderr, "  c create  - add files to x.zip\n");
  fprintf(stderr,
          "  f flatten - flatten files to use with create or "
          "extract operation\n");
  fprintf(stderr,
          "  C compress - compress files when using the create operation\n");
  fprintf(stderr, "x and c cannot be used in the same command-line.\n");
  fprintf(stderr,
          "\nFor every file, a path in the zip can be specified. Examples:\n");
  fprintf(stderr,
          "  zipper c x.zip a/b/__init__.py= # Add an empty file at "
          "a/b/__init__.py\n");
  fprintf(stderr,
          "  zipper c x.zip a/b/main.py=foo/bar/bin.py # Add file "
          "foo/bar/bin.py at a/b/main.py\n");
  fprintf(stderr,
          "\nIf the zip path is not specified, it is assumed to be the file "
          "path.\n");
  exit(1);
}

int main(int argc, char **argv) {
  bool extract = false;
  bool verbose = false;
  bool create = false;
  bool compress = false;
  bool flatten = false;

  if (argc < 3) {
    usage(argv[0]);
  }

  for (int i = 0; argv[1][i] != 0; i++) {
    switch (argv[1][i]) {
    case 'x':
      extract = true;
      break;
    case 'v':
      verbose = true;
      break;
    case 'c':
      create = true;
      break;
    case 'f':
      flatten = true;
      break;
    case 'C':
      compress = true;
      break;
    default:
      usage(argv[0]);
    }
  }

  // x and c cannot be used in the same command-line.
  if (create && extract) {
    usage(argv[0]);
  }

  // Calculate the argument index of the first entry file.
  int filelist_start_index;
  if (argc > 3 && strcmp(argv[3], "-d") == 0) {
    filelist_start_index = 5;
  } else {
    filelist_start_index = 3;
  }

  char** filelist = NULL;

  // We have one option file. Read and extract the content.
  if (argc == filelist_start_index + 1 &&
      argv[filelist_start_index][0] == '@') {
    char* filelist_name = argv[filelist_start_index];
    filelist = devtools_ijar::read_filelist(filelist_name + 1);
    if (filelist == NULL) {
      fprintf(stderr, "Can't read file list %s: %s.\n", filelist_name,
              strerror(errno));
      return -1;
    }
    // We have more than one files. Assume that they are all file entries.
  } else if (argc >= filelist_start_index + 1) {
    filelist = argv + filelist_start_index;
  } else {
    // There are no entry files specified. This is forbidden if we are creating
    // a zip file.
    if (create) {
      fprintf(stderr, "Can't create zip without input files specified.");
      return -1;
    }
  }

  if (create) {
    // Create a zip
    return devtools_ijar::create(argv[2], filelist, flatten, verbose, compress);
  } else {
    char* exdir = NULL;
    if (argc > 3 && strcmp(argv[3], "-d") == 0) {
      exdir = argv[4];
    }

    // Extraction / list mode
    return devtools_ijar::extract(argv[2], exdir, filelist, verbose, extract,
                                  flatten);
  }
}
