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

#ifndef BAZEL_SRC_TOOLS_SINGLEJAR_INPUT_JAR_H_
#define BAZEL_SRC_TOOLS_SINGLEJAR_INPUT_JAR_H_ 1

#define __STDC_FORMAT_MACROS 1

#include <inttypes.h>
#include <stdlib.h>

#include <string>

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

/*
 * An input jar. The usage pattern is:
 *   InputJar input_jar;
 *   if (!input_jar.Open("path/to/file")) { fail...}
 *   CDH *dir_entry;
 *   LH *local_header;
 *   while (dir_entry = input_jar.NextEntry(&local_header)) {
 *     // process entry.
 *   }
 *   input_jar.Close(); // actually, called by destructor, too.
 */
class InputJar {
 public:
  InputJar() {}

  ~InputJar() { Close(); }

  int fd() const { return mapped_file_.fd(); }

  // Opens the file, memory maps it and locates Central Directory.
  bool Open(const std::string& path);

  // Returns the next Central Directory Header or NULL.
  const CDH *NextEntry(const LH **local_header_ptr) {
    if (path_.empty()) {
      diag_errx(1, "%s:%d: call Open() first!", __FILE__, __LINE__);
    }
    if (!cdh_->is()) {
      return nullptr;
    }
    const CDH *current_cdh = cdh_;
    const uint8_t *new_cdr = ziph::byte_ptr(cdh_) + cdh_->size();
    if (!mapped_file_.mapped(new_cdr)) {
      diag_errx(
          1,
          "Bad directory record at offset 0x%" PRIx64 " of %s\n"
          "file name length = %u, extra_field length = %u, comment length = %u",
          CentralDirectoryRecordOffset(cdh_), path_.c_str(),
          cdh_->file_name_length(), cdh_->extra_fields_length(),
          cdh_->comment_length());
    }
    cdh_ = reinterpret_cast<const CDH *>(new_cdr);
    *local_header_ptr = LocalHeader(current_cdh);
    return current_cdh;
  }

  // Closes the file.
  bool Close();

  uint64_t CentralDirectoryRecordOffset(const void *cdr) const {
    return mapped_file_.offset(cdr);
  }

  const LH *LocalHeader(const CDH *cdh) const {
    return reinterpret_cast<const LH *>(
        mapped_file_.address(cdh->local_header_offset() + preamble_size_));
  }

  uint64_t LocalHeaderOffset(const LH *lh) const {
    return mapped_file_.offset(lh);
  }

  const uint8_t *mapped_start() const {
    return mapped_file_.address(0);
  }

 private:
  std::string path_;
  MappedFile mapped_file_;
  const CDH *cdh_;  // current directory entry
  uint64_t preamble_size_;  // Bytes before the Zip proper.
};

#endif  //  BAZEL_SRC_TOOLS_SINGLEJAR_INPUT_JAR_H_
