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

/*
 * Check processing jar with preamble.
 *
 * A jar/zip file may contain a preambleL: an arbitrary data before
 * the actual entries, and the decompressors (e.g., unzip) can handle
 * this. This feature can be used to create "self-extracting"
 * archives: use 'cat' command to prepend a binary implementing the
 * extractor to a zip archive, and then run 'zip -A' on the result to
 * adjust the entry offsets stored in the zip archive. Actually, some
 * of the archive reading code works even if 'zip -A' wasn't run.
 */

#include <errno.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <memory>
#include <string>

#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/port.h"
#include "src/main/cpp/util/strings.h"
#include "src/tools/singlejar/input_jar.h"
#include "src/tools/singlejar/test_util.h"
#include "googletest/include/gtest/gtest.h"

namespace {

using bazel::tools::cpp::runfiles::Runfiles;

void Verify(const std::string &path) {
  InputJar input_jar;
  ASSERT_TRUE(input_jar.Open(path));
  const LH *lh;
  const CDH *cdh;
  while ((cdh = input_jar.NextEntry(&lh))) {
    ASSERT_TRUE(cdh->is())
        << "No expected tag in the Central Directory Entry.";
    ASSERT_NE(nullptr, lh) << "No local header.";
    ASSERT_TRUE(lh->is()) << "No expected tag in the Local Header.";
    EXPECT_EQ(lh->file_name_string(), cdh->file_name_string());
    if (!cdh->no_size_in_local_header()) {
      EXPECT_EQ(lh->compressed_file_size(), cdh->compressed_file_size())
          << "Entry: " << lh->file_name_string();
      EXPECT_EQ(lh->uncompressed_file_size(), cdh->uncompressed_file_size())
          << "Entry: " << cdh->file_name_string();
    }
  }
  input_jar.Close();
}

// Archive not containing 64-bit End of Central Directory/Locator with preamble.
TEST(InputJarPreambledTest, Small) {
  std::unique_ptr<Runfiles> runfiles(Runfiles::CreateForTest());
  std::string out_path = singlejar_test_util::OutputFilePath("out.jwp");
  std::string exe_path = singlejar_test_util::OutputFilePath("exe");
  ASSERT_TRUE(singlejar_test_util::AllocateFile(exe_path, 100));
  ASSERT_EQ(
      0,
      singlejar_test_util::RunCommand(
          "cat", exe_path.c_str(),
          runfiles
              ->Rlocation(
                  "io_bazel/src/tools/singlejar/libtest1.jar")
              .c_str(),
          ">", out_path.c_str(), nullptr));
  Verify(out_path);
}

// Same as above with zip -A applied to the file.
TEST(InputJarPreambledTest, SmallAdjusted) {
  std::unique_ptr<Runfiles> runfiles(Runfiles::CreateForTest());
  std::string out_path = singlejar_test_util::OutputFilePath("out.jwp");
  std::string exe_path = singlejar_test_util::OutputFilePath("exe");
  ASSERT_TRUE(singlejar_test_util::AllocateFile(exe_path, 100));
  ASSERT_EQ(
      0,
      singlejar_test_util::RunCommand(
          "cat", exe_path.c_str(),
          runfiles
              ->Rlocation(
                  "io_bazel/src/tools/singlejar/libtest1.jar")
              .c_str(),
          ">", out_path.c_str(), nullptr));
  ASSERT_EQ(0, singlejar_test_util::RunCommand("zip", "-A", out_path.c_str(),
                                               nullptr));
  Verify(out_path);
}

// 64-bit Zip file with preamble
TEST(InputJarPreambledTest, Huge) {
  std::string file4g = singlejar_test_util::OutputFilePath("file4g");
  ASSERT_TRUE(singlejar_test_util::AllocateFile(file4g, 0x10000000F));
  std::string huge_jar = singlejar_test_util::OutputFilePath("huge.jar");
  ASSERT_EQ(0, singlejar_test_util::RunCommand("zip", "-0m", huge_jar.c_str(),
                                               file4g.c_str(), nullptr));
  std::string exe_path = singlejar_test_util::OutputFilePath("exe");
  std::string out_path = singlejar_test_util::OutputFilePath("out.jwp");
  ASSERT_EQ(0,
            singlejar_test_util::RunCommand("cat", exe_path.c_str(),
                                            huge_jar.c_str(),
                                            ">", out_path.c_str(), nullptr));
  Verify(out_path);
}

}  // namespace
