// Copyright 2016 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.

#include "src/tools/singlejar/combiners.h"

#include <cctype>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>

#include "src/tools/singlejar/diag.h"

Combiner::~Combiner() {}

Concatenator::~Concatenator() {}

bool Concatenator::Merge(const CDH *cdh, const LH *lh) {
  if (insert_newlines_ && buffer_.get() && buffer_->data_size() &&
      '\n' != buffer_->last_byte()) {
    Append("\n", 1);
  }
  CreateBuffer();
  if (Z_NO_COMPRESSION == lh->compression_method()) {
    buffer_->ReadEntryContents(lh);
  } else if (Z_DEFLATED == lh->compression_method()) {
    if (!inflater_) {
      inflater_.reset(new Inflater());
    }
    buffer_->DecompressEntryContents(cdh, lh, inflater_.get());
  } else {
    diag_errx(2, "%s is neither stored nor deflated", filename_.c_str());
  }
  return true;
}

void *Concatenator::OutputEntry(bool compress) {
  if (!buffer_) {
    return nullptr;
  }

  // Allocate a contiguous buffer for the local file header and
  // deflated data. We assume that deflate decreases the size, so if
  //  the deflater reports overflow, we just save original data.
  size_t deflated_buffer_size =
      sizeof(LH) + filename_.size() + buffer_->data_size();

  // Huge entry (>4GB) needs Zip64 extension field with 64-bit original
  // and compressed size values.
  uint8_t
      zip64_extension_buffer[sizeof(Zip64ExtraField) + 2 * sizeof(uint64_t)];
  bool huge_buffer = ziph::zfield_needs_ext64(buffer_->data_size());
  if (huge_buffer) {
    deflated_buffer_size += sizeof(zip64_extension_buffer);
  }
  LH *lh = reinterpret_cast<LH *>(malloc(deflated_buffer_size));
  if (lh == nullptr) {
    return nullptr;
  }
  lh->signature();
  lh->version(20);
  lh->bit_flag(0x0);
  lh->last_mod_file_time(1);                     // 00:00:01
  lh->last_mod_file_date(30 << 9 | 1 << 5 | 1);  // 2010-01-01
  lh->crc32(0x12345678);
  lh->compressed_file_size32(0);
  lh->file_name(filename_.c_str(), filename_.size());

  if (huge_buffer) {
    // Add Z64 extension if this is a huge entry.
    lh->uncompressed_file_size32(0xFFFFFFFF);
    Zip64ExtraField *z64 =
        reinterpret_cast<Zip64ExtraField *>(zip64_extension_buffer);
    z64->signature();
    z64->payload_size(2 * sizeof(uint64_t));
    z64->attr64(0, buffer_->data_size());
    lh->extra_fields(reinterpret_cast<uint8_t *>(z64), z64->size());
  } else {
    lh->uncompressed_file_size32(buffer_->data_size());
    lh->extra_fields(nullptr, 0);
  }

  uint32_t checksum;
  uint64_t compressed_size;
  uint16_t method;
  if (compress) {
    method = buffer_->CompressOut(lh->data(), &checksum, &compressed_size);
  } else {
    buffer_->CopyOut(lh->data(), &checksum);
    method = Z_NO_COMPRESSION;
    compressed_size = buffer_->data_size();
  }
  lh->crc32(checksum);
  lh->compression_method(method);
  if (huge_buffer) {
    lh->compressed_file_size32(ziph::zfield_needs_ext64(compressed_size)
                                   ? 0xFFFFFFFF
                                   : compressed_size);
    // Not sure if this has to be written in the small case, but it shouldn't
    // hurt.
    const_cast<Zip64ExtraField *>(lh->zip64_extra_field())
        ->attr64(1, compressed_size);
  } else {
    // If original data is <4GB, the compressed one is, too.
    lh->compressed_file_size32(compressed_size);
  }
  return reinterpret_cast<void *>(lh);
}

NullCombiner::~NullCombiner() {}

bool NullCombiner::Merge(const CDH * /*cdh*/, const LH * /*lh*/) {
  return true;
}

void *NullCombiner::OutputEntry(bool /*compress*/) { return nullptr; }

XmlCombiner::~XmlCombiner() {}

bool XmlCombiner::Merge(const CDH *cdh, const LH *lh) {
  if (!concatenator_) {
    concatenator_.reset(new Concatenator(filename_, false));
    concatenator_->Append(start_tag_);
    concatenator_->Append("\n");
  }
  // To ensure xml concatentation is idempotent, read in the entry being added
  // and remove the start and end tags if they are present.
  TransientBytes bytes_;
  if (Z_NO_COMPRESSION == lh->compression_method()) {
    bytes_.ReadEntryContents(lh);
  } else if (Z_DEFLATED == lh->compression_method()) {
    if (!inflater_) {
      inflater_.reset(new Inflater());
    }
    bytes_.DecompressEntryContents(cdh, lh, inflater_.get());
  } else {
    diag_errx(2, "%s is neither stored nor deflated", filename_.c_str());
  }
  uint32_t checksum;
  char *buf = reinterpret_cast<char *>(malloc(bytes_.data_size()));
  // TODO(b/37631490): optimize this to avoid copying the bytes twice
  bytes_.CopyOut(reinterpret_cast<uint8_t *>(buf), &checksum);
  int start_offset = 0;
  if (strncmp(buf, start_tag_.c_str(), start_tag_.length()) == 0) {
    start_offset = start_tag_.length();
  }
  uint64_t end = bytes_.data_size();
  while (end >= end_tag_.length() && std::isspace(buf[end - 1])) end--;
  if (strncmp(buf + end - end_tag_.length(), end_tag_.c_str(),
              end_tag_.length()) == 0) {
    end -= end_tag_.length();
  } else {
    // Leave trailing whitespace alone if we didn't find a match.
    end = bytes_.data_size();
  }
  concatenator_->Append(buf + start_offset, end - start_offset);
  free(buf);
  return true;
}

void *XmlCombiner::OutputEntry(bool compress) {
  if (!concatenator_) {
    return nullptr;
  }
  concatenator_->Append(end_tag_);
  concatenator_->Append("\n");
  return concatenator_->OutputEntry(compress);
}

PropertyCombiner::~PropertyCombiner() {}

bool PropertyCombiner::Merge(const CDH * /*cdh*/, const LH * /*lh*/) {
  return false;  // This should not be called.
}

ManifestCombiner::~ManifestCombiner() {}

static const char *MULTI_RELEASE = "Multi-Release: true";
static const size_t MULTI_RELEASE_LENGTH = strlen(MULTI_RELEASE);

static const char *MULTI_RELEASE_PREFIX = "Multi-Release: ";
static const size_t MULTI_RELEASE_PREFIX_LENGTH = strlen(MULTI_RELEASE_PREFIX);

static const char *ADD_EXPORTS_PREFIX = "Add-Exports: ";
static const size_t ADD_EXPORTS_PREFIX_LENGTH = strlen(ADD_EXPORTS_PREFIX);

static const char *ADD_OPENS_PREFIX = "Add-Opens: ";
static const size_t ADD_OPENS_PREFIX_LENGTH = strlen(ADD_OPENS_PREFIX);

void ManifestCombiner::EnableMultiRelease() { multi_release_ = true; }

void ManifestCombiner::AddExports(const std::vector<std::string> &add_exports) {
  add_exports_.insert(std::end(add_exports_), std::begin(add_exports),
                      std::end(add_exports));
}

void ManifestCombiner::AddOpens(const std::vector<std::string> &add_opens) {
  add_opens_.insert(std::end(add_opens_), std::begin(add_opens),
                    std::end(add_opens));
}

bool ManifestCombiner::HandleModuleFlags(std::vector<std::string> &output,
                                         const char *key, size_t key_length,
                                         std::string line) {
  if (line.find(key, 0, key_length) == std::string::npos) {
    return false;
  }
  std::istringstream iss(line.substr(key_length));
  std::copy(std::istream_iterator<std::string>(iss),
            std::istream_iterator<std::string>(), std::back_inserter(output));
  return true;
}

void ManifestCombiner::AppendLine(const std::string &line) {
  if (line.find(MULTI_RELEASE_PREFIX, 0, MULTI_RELEASE_PREFIX_LENGTH) !=
      std::string::npos) {
    if (line.find("true", MULTI_RELEASE_PREFIX_LENGTH) != std::string::npos) {
      multi_release_ = true;
    } else if (line.find("false", MULTI_RELEASE_PREFIX_LENGTH) !=
               std::string::npos) {
      multi_release_ = false;
    }
    return;
  }
  // Handle 'Add-Exports:' and 'Add-Opens:' lines in --deploy_manifest_lines and
  // merge them with the --add_exports= and --add_opens= flags.
  if (HandleModuleFlags(add_exports_, ADD_EXPORTS_PREFIX,
                        ADD_EXPORTS_PREFIX_LENGTH, line)) {
    return;
  }
  if (HandleModuleFlags(add_opens_, ADD_OPENS_PREFIX, ADD_OPENS_PREFIX_LENGTH,
                        line)) {
    return;
  }
  concatenator_->Append(line);
  if (line[line.size() - 1] != '\n') {
    concatenator_->Append("\r\n");
  }
}

bool ManifestCombiner::Merge(const CDH *cdh, const LH *lh) {
  // Ignore Multi-Release attributes in inputs: we write the manifest first,
  // before inputs are processed, so we reply on  deploy_manifest_lines to
  // create Multi-Release jars instead of doing it automatically based on
  // the inputs.
  return true;
}

void ManifestCombiner::OutputModuleFlags(std::vector<std::string> &flags,
                                         const char *key) {
  std::sort(flags.begin(), flags.end());
  flags.erase(std::unique(flags.begin(), flags.end()), flags.end());
  if (!flags.empty()) {
    concatenator_->Append(key);
    bool first = true;
    for (const auto &flag : flags) {
      if (!first) {
        concatenator_->Append("\r\n  ");
      }
      concatenator_->Append(flag);
      first = false;
    }
    concatenator_->Append("\r\n");
  }
}

void *ManifestCombiner::OutputEntry(bool compress) {
  if (multi_release_) {
    concatenator_->Append(MULTI_RELEASE);
    concatenator_->Append("\r\n");
  }
  OutputModuleFlags(add_exports_, ADD_EXPORTS_PREFIX);
  OutputModuleFlags(add_opens_, ADD_OPENS_PREFIX);
  concatenator_->Append("\r\n");
  return concatenator_->OutputEntry(compress);
}
