// Copyright 2017 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/desugar_checking.h"
#include "src/tools/singlejar/diag.h"
#include "src/main/protobuf/desugar_deps.pb.h"

bool Java8DesugarDepsChecker::Merge(const CDH *cdh, const LH *lh) {
  // Throw away anything previously read, no need to concatenate
  buffer_.reset(new TransientBytes());
  if (Z_NO_COMPRESSION == lh->compression_method()) {
    buffer_->ReadEntryContents(lh);
  } else if (Z_DEFLATED == lh->compression_method()) {
    if (!inflater_.get()) {
      inflater_.reset(new Inflater());
    }
    buffer_->DecompressEntryContents(cdh, lh, inflater_.get());
  } else {
    errx(2, "META-INF/desugar_deps is neither stored nor deflated");
  }

  // TODO(kmb): Wrap buffer_ as ZeroCopyInputStream to avoid copying out.
  // Note we only copy one file at a time, so overhead should be modest.
  uint32_t checksum;
  const size_t data_size = buffer_->data_size();
  uint8_t *buf = reinterpret_cast<uint8_t *>(malloc(data_size));
  buffer_->CopyOut(reinterpret_cast<uint8_t *>(buf), &checksum);
  buffer_.reset();  // release buffer eagerly

  bazel::tools::desugar::DesugarDepsInfo deps_info;
  google::protobuf::io::CodedInputStream content(buf, data_size);
  if (!deps_info.ParseFromCodedStream(&content)) {
    errx(2, "META-INF/desugar_deps: unable to parse");
  }
  if (!content.ConsumedEntireMessage()) {
    errx(2, "META-INF/desugar_deps: unexpected trailing content");
  }
  free(buf);

  for (const auto &assume_present : deps_info.assume_present()) {
    // This means we need file named <target>.class in the output.  Remember
    // the first origin of this requirement for error messages, drop others.
    needed_deps_.emplace(assume_present.target().binary_name() + ".class",
                         assume_present.origin().binary_name());
  }

  for (const auto &missing : deps_info.missing_interface()) {
    // Remember the first origin of this requirement for error messages, drop
    // subsequent ones.
    missing_interfaces_.emplace(missing.target().binary_name(),
                                missing.origin().binary_name());
  }

  for (const auto &extends : deps_info.interface_with_supertypes()) {
    // Remember interface hierarchy the first time we see this interface, drop
    // subsequent ones for consistency with how singlejar will keep the first
    // occurrence of the file defining the interface.  We'll lazily derive
    // whether missing_interfaces_ inherit default methods with this data later.
    if (extends.extended_interface_size() > 0) {
      std::vector<std::string> extended;
      extended.reserve(extends.extended_interface_size());
      for (const auto &itf : extends.extended_interface()) {
        extended.push_back(itf.binary_name());
      }
      extended_interfaces_.emplace(extends.origin().binary_name(),
                                   std::move(extended));
    }
  }

  for (const auto &companion : deps_info.interface_with_companion()) {
    // Only remember interfaces that definitely have default methods for now.
    // For all other interfaces we'll transitively check extended interfaces
    // in HasDefaultMethods.
    if (companion.num_default_methods() > 0) {
      has_default_methods_[companion.origin().binary_name()] = true;
    }
  }
  return true;
}

void *Java8DesugarDepsChecker::OutputEntry(bool compress) {
  if (verbose_) {
    fprintf(stderr, "Needed deps: %lu\n", needed_deps_.size());
    fprintf(stderr, "Interfaces to check: %lu\n", missing_interfaces_.size());
    fprintf(stderr, "Sub-interfaces: %lu\n", extended_interfaces_.size());
    fprintf(stderr, "Interfaces w/ default methods: %lu\n",
            has_default_methods_.size());
  }
  for (auto needed : needed_deps_) {
    if (verbose_) {
      fprintf(stderr, "Looking for %s\n", needed.first.c_str());
    }
    if (!known_member_(needed.first)) {
      if (fail_on_error_) {
        errx(2, "%s referenced by %s but not found.  Is the former defined in "
                "a neverlink library?",
                needed.first.c_str(), needed.second.c_str());
      } else {
        error_ = true;
      }
    }
  }

  for (auto missing : missing_interfaces_) {
    if (verbose_) {
      fprintf(stderr, "Checking %s\n", missing.first.c_str());
    }
    if (HasDefaultMethods(missing.first)) {
      if (fail_on_error_) {
        errx(2, "%s needed on the classpath for desugaring %s.  Please add the "
                "missing dependency to the target containing the latter.",
                missing.first.c_str(), missing.second.c_str());
      } else {
        error_ = true;
      }
    }
  }

  // We don't want these files in the output, just check them for consistency
  return nullptr;
}

bool Java8DesugarDepsChecker::HasDefaultMethods(
    const std::string &interface_name) {
  auto cached = has_default_methods_.find(interface_name);
  if (cached != has_default_methods_.end()) {
    return cached->second;
  }

  // Prime with false in case there's a cycle.  We'll update with the true value
  // (ignoring the cycle) below.
  has_default_methods_.emplace(interface_name, false);

  for (const std::string &extended : extended_interfaces_[interface_name]) {
    if (HasDefaultMethods(extended)) {
      has_default_methods_[interface_name] = true;
      return true;
    }
  }
  has_default_methods_[interface_name] = false;
  return false;
}
