// Copyright (C) 2019 The Android Open Source Project
//
// 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.

package com.googlesource.gerrit.plugins.copyright.lib;

import com.google.common.collect.ImmutableList;
import java.io.BufferedInputStream;
import java.io.IOException;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ar.ArArchiveInputStream;
import org.apache.commons.compress.archivers.arj.ArjArchiveInputStream;
import org.apache.commons.compress.archivers.cpio.CpioArchiveEntry;
import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream;
import org.apache.commons.compress.archivers.dump.DumpArchiveEntry;
import org.apache.commons.compress.archivers.dump.DumpArchiveInputStream;
import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
import org.apache.commons.compress.archivers.jar.JarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;

/** Encapsulates the differences among the known ArchiveInputStream/ArchiveEntry pairs. */
public abstract class Archive {

  /** The know archive file types. */
  private static final ImmutableList<Archive> archives =
      ImmutableList.of(
          new ArFile(),
          new ArjFile(),
          new CpioFile(),
          new DumpFile(),
          new JarFile(),
          new TarFile(),
          new ZipFile());

  /** Returns the Archive to use based on `fileName` or null if not a known archive file format. */
  public static Archive getArchive(String fileName) {
    for (Archive archive : archives) {
      if (archive.isArchive(fileName)) {
        return archive;
      }
    }
    return null;
  }

  /** Returns true if `fileName` identifies an instance of the archive file type. */
  protected abstract boolean isArchive(String fileName);

  /** Wraps `source` with the `ArchiveInputStream` type for the archive file type. */
  public abstract ArchiveInputStream newStream(BufferedInputStream source) throws ArchiveException;

  /** Returns the next `ArchiveEntry` in `archive` for the archive file type. */
  public abstract ArchiveEntry getNext(ArchiveInputStream archive)
      throws ArchiveException, IOException;

  /** Returns true if `entry` describes a regular file in the archive. */
  public abstract boolean isRegularFile(ArchiveEntry entry);

  /** Archives created with the `ar` command or equivalent. */
  private static final class ArFile extends Archive {
    @Override
    protected boolean isArchive(String fileName) {
      return fileName.endsWith(".a")
          || fileName.endsWith(".deb")
          || fileName.endsWith(".ar")
          || fileName.endsWith("-ar")
          || fileName.endsWith("-deb")
          || fileName.endsWith("-a");
    }

    @Override
    public ArchiveInputStream newStream(BufferedInputStream source) throws ArchiveException {
      return new ArArchiveInputStream(source);
    }

    @Override
    public ArchiveEntry getNext(ArchiveInputStream archive) throws ArchiveException, IOException {
      return ((ArArchiveInputStream) archive).getNextArEntry();
    }

    @Override
    public boolean isRegularFile(ArchiveEntry entry) {
      return !entry.isDirectory();
    }
  }

  /** Archives created with the `arj` command. */
  private static final class ArjFile extends Archive {
    @Override
    protected boolean isArchive(String fileName) {
      return fileName.endsWith(".arj");
    }

    @Override
    public ArchiveInputStream newStream(BufferedInputStream source) throws ArchiveException {
      return new ArjArchiveInputStream(source);
    }

    @Override
    public ArchiveEntry getNext(ArchiveInputStream archive) throws ArchiveException, IOException {
      return ((ArjArchiveInputStream) archive).getNextEntry();
    }

    @Override
    public boolean isRegularFile(ArchiveEntry entry) {
      return !entry.isDirectory();
    }
  }

  /** Archives created with the `cpio` command. */
  private static final class CpioFile extends Archive {
    @Override
    protected boolean isArchive(String fileName) {
      return fileName.endsWith(".cpio");
    }

    @Override
    public ArchiveInputStream newStream(BufferedInputStream source) throws ArchiveException {
      return new CpioArchiveInputStream(source);
    }

    @Override
    public ArchiveEntry getNext(ArchiveInputStream archive) throws ArchiveException, IOException {
      return ((CpioArchiveInputStream) archive).getNextCPIOEntry();
    }

    @Override
    public boolean isRegularFile(ArchiveEntry entry) {
      return ((CpioArchiveEntry) entry).isRegularFile();
    }
  }

  /** Archives created with the `dump` command. */
  private static final class DumpFile extends Archive {
    @Override
    protected boolean isArchive(String fileName) {
      return fileName.endsWith(".dump") || fileName.endsWith(".dmp");
    }

    @Override
    public ArchiveInputStream newStream(BufferedInputStream source) throws ArchiveException {
      return new DumpArchiveInputStream(source);
    }

    @Override
    public ArchiveEntry getNext(ArchiveInputStream archive) throws ArchiveException, IOException {
      return ((DumpArchiveInputStream) archive).getNextDumpEntry();
    }

    @Override
    public boolean isRegularFile(ArchiveEntry entry) {
      return ((DumpArchiveEntry) entry).isFile();
    }
  }

  /** Java archives and equivalents. Internally structured as special cases of zip files. */
  private static final class JarFile extends Archive {
    @Override
    protected boolean isArchive(String fileName) {
      return fileName.endsWith(".jar")
          || fileName.endsWith(".aar")
          || fileName.endsWith(".apk")
          || fileName.endsWith(".apex")
          || fileName.endsWith(".war")
          || fileName.endsWith(".rar")
          || fileName.endsWith(".ear")
          || fileName.endsWith(".sar")
          || fileName.endsWith(".par")
          || fileName.endsWith(".kar")
          || fileName.endsWith("-jar");
    }

    @Override
    public ArchiveInputStream newStream(BufferedInputStream source) throws ArchiveException {
      return new JarArchiveInputStream(source);
    }

    @Override
    public ArchiveEntry getNext(ArchiveInputStream archive) throws ArchiveException, IOException {
      return ((JarArchiveInputStream) archive).getNextJarEntry();
    }

    @Override
    public boolean isRegularFile(ArchiveEntry entry) {
      JarArchiveEntry e = (JarArchiveEntry) entry;
      return !e.isDirectory() && !e.isUnixSymlink();
    }
  }

  /** Archives created with the `tar` command or equivalent. */
  private static final class TarFile extends Archive {
    @Override
    protected boolean isArchive(String fileName) {
      return fileName.endsWith(".tar") || fileName.endsWith("-tar") || fileName.endsWith(".pax");
    }

    @Override
    public ArchiveInputStream newStream(BufferedInputStream source) throws ArchiveException {
      return new TarArchiveInputStream(source);
    }

    @Override
    public ArchiveEntry getNext(ArchiveInputStream archive) throws ArchiveException, IOException {
      return ((TarArchiveInputStream) archive).getNextTarEntry();
    }

    @Override
    public boolean isRegularFile(ArchiveEntry entry) {
      return ((TarArchiveEntry) entry).isFile();
    }
  }

  /**
   * Archives created with the `zip` command or equivalent.
   *
   * <p>Many standard file types are internally structured as zip files.
   */
  private static final class ZipFile extends Archive {
    @Override
    protected boolean isArchive(String fileName) {
      return fileName.endsWith(".zip")
          || fileName.endsWith(".ZIP")
          || fileName.endsWith("-zip")
          || fileName.endsWith("-ZIP")
          || fileName.endsWith(".sfx")
          || fileName.endsWith(".docx")
          || fileName.endsWith(".docm")
          || fileName.endsWith(".xlsx")
          || fileName.endsWith(".xlsm")
          || fileName.endsWith(".pptx")
          || fileName.endsWith(".pptm")
          || fileName.endsWith(".odf")
          || fileName.endsWith(".odt")
          || fileName.endsWith(".odp")
          || fileName.endsWith(".ods")
          || fileName.endsWith(".odg");
    }

    @Override
    public ArchiveInputStream newStream(BufferedInputStream source) throws ArchiveException {
      return new ZipArchiveInputStream(source);
    }

    @Override
    public ArchiveEntry getNext(ArchiveInputStream archive) throws ArchiveException, IOException {
      return ((ZipArchiveInputStream) archive).getNextZipEntry();
    }

    @Override
    public boolean isRegularFile(ArchiveEntry entry) {
      ZipArchiveEntry e = (ZipArchiveEntry) entry;
      return !e.isDirectory() && !e.isUnixSymlink();
    }
  }
}
