// 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.
package com.google.devtools.build.android;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Ordering;
import com.google.devtools.build.android.aapt2.ResourceCompiler;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.annotation.Nullable;

/** Collects all the functionationality for an action to create the final output artifacts. */
public class AndroidResourceOutputs {

  @VisibleForTesting
  static class ZipBuilder implements Closeable {
    // ZIP timestamps have a resolution of 2 seconds.
    // see http://www.info-zip.org/FAQ.html#limits
    private static final long MINIMUM_TIMESTAMP_INCREMENT = 2000L;

    // The earliest date representable in a zip file, 1-1-1980 (the DOS epoch).
    private static final long ZIP_EPOCH =
        new GregorianCalendar(1980, Calendar.JANUARY, 01, 0, 0).getTimeInMillis();

    private final ZipOutputStream zip;

    private ZipBuilder(ZipOutputStream zip) {
      this.zip = zip;
    }

    public static ZipBuilder createFor(Path archivePath) throws IOException {
      return wrap(
          new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(archivePath))));
    }

    public static ZipBuilder wrap(ZipOutputStream zip) {
      return new ZipBuilder(zip);
    }

    /**
     * Normalize timestamps for deterministic builds. Stamp .class files to be a bit newer than
     * .java files. See: {@link
     * com.google.devtools.build.buildjar.jarhelper.JarHelper#normalizedTimestamp(String)}
     */
    protected long normalizeTime(String filename) {
      if (filename.endsWith(".class")) {
        return ZIP_EPOCH + MINIMUM_TIMESTAMP_INCREMENT;
      } else {
        return ZIP_EPOCH;
      }
    }

    protected void addEntry(ZipEntry entry, byte[] content) throws IOException {
      // Create a new ZipEntry because there are occasional discrepancies
      // between the metadata and written content.
      addEntry(entry.getName(), content, entry.getMethod());
    }

    protected void addEntry(String rawName, byte[] content, int storageMethod) throws IOException {
      addEntry(rawName, content, storageMethod, null);
    }

    protected void addEntry(
        String rawName, byte[] content, int storageMethod, @Nullable String comment)
        throws IOException {
      // Fix the path for windows.
      String relativeName = rawName.replace('\\', '/');
      // Make sure the zip entry is not absolute.
      Preconditions.checkArgument(
          !relativeName.startsWith("/"), "Cannot add absolute resources %s", relativeName);
      ZipEntry entry = new ZipEntry(relativeName);
      entry.setMethod(storageMethod);
      entry.setTime(normalizeTime(relativeName));
      entry.setSize(content.length);
      CRC32 crc32 = new CRC32();
      crc32.update(content);
      entry.setCrc(crc32.getValue());
      if (!Strings.isNullOrEmpty(comment)) {
        entry.setComment(comment);
      }

      zip.putNextEntry(entry);
      zip.write(content);
      zip.closeEntry();
    }

    @Override
    public void close() throws IOException {
      zip.close();
    }
  }

  /** A ZipBuilder that avoids adding the same entry twice, storing only the first occurrence. */
  public static class UniqueZipBuilder extends ZipBuilder {

    /** A set of all entry names (e.g. "foo/bar.txt") that have been added to the underlying zip. */
    private final Set<String> addedEntryNames = new LinkedHashSet<>();

    private UniqueZipBuilder(ZipOutputStream zip) {
      super(zip);
    }

    public static UniqueZipBuilder createFor(Path archivePath) throws IOException {
      return new UniqueZipBuilder(
          new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(archivePath))));
    }

    @Override
    public void addEntry(ZipEntry entry, byte[] content) throws IOException {
      addEntry(entry.getName(), content, entry.getMethod());
    }

    @Override
    public void addEntry(String rawName, byte[] content, int storageMethod) throws IOException {
      // Fix the path for Windows (required to ensure entry name isn't duplicated by call to super).
      String relativeName = rawName.replace('\\', '/');
      if (!addedEntryNames.add(relativeName)) {
        return;
      }
      super.addEntry(relativeName, content, storageMethod);
    }

    public void addDirEntry(String rawName) throws IOException {
      String dirName = rawName + (rawName.endsWith("/") ? "" : "/");
      addEntry(dirName, new byte[0], ZipEntry.STORED);
    }
  }

  /** A FileVisitor that will add all R class files to be stored in a zip archive. */
  static final class ClassJarBuildingVisitor extends ZipBuilderVisitor {

    ClassJarBuildingVisitor(ZipBuilder zip, Path root) {
      super(zip, root, null);
    }

    private byte[] manifestContent(@Nullable String targetLabel, @Nullable String injectingRuleKind)
        throws IOException {
      Manifest manifest = new Manifest();
      Attributes attributes = manifest.getMainAttributes();
      attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
      Attributes.Name createdBy = new Attributes.Name("Created-By");
      if (attributes.getValue(createdBy) == null) {
        attributes.put(createdBy, "bazel");
      }
      if (targetLabel != null) {
        // Enable add_deps support. add_deps expects this attribute in the jar manifest.
        attributes.putValue("Target-Label", targetLabel);
      }
      if (injectingRuleKind != null) {
        // add_deps support for aspects. Usually null.
        attributes.putValue("Injecting-Rule-Kind", injectingRuleKind);
      }
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      manifest.write(out);
      return out.toByteArray();
    }

    @Override
    protected void writeEntry(Path file) throws IOException {
      Path filename = file.getFileName();
      String name = filename.toString();
      if (name.endsWith(".class")) {
        byte[] content = Files.readAllBytes(file);
        addEntry(file, content);
      }
    }

    void writeManifestContent(@Nullable String targetLabel, @Nullable String injectingRuleKind)
        throws IOException {
      addEntry("META-INF/", new byte[] {});
      addEntry("META-INF/MANIFEST.MF", manifestContent(targetLabel, injectingRuleKind));
    }
  }

  /** A FileVisitor that will add all R.java files to be stored in a zip archive. */
  static final class SymbolFileSrcJarBuildingVisitor extends ZipBuilderVisitor {

    static final Pattern ID_PATTERN =
        Pattern.compile("public static int ([\\w\\.]+)=0x[0-9A-fa-f]+;");
    static final Pattern INNER_CLASS =
        Pattern.compile("public static class ([a-z_]*) \\{(.*?)\\}", Pattern.DOTALL);
    static final Pattern PACKAGE_PATTERN =
        Pattern.compile("\\s*package ([a-zA-Z_$][a-zA-Z\\d_$]*(?:\\.[a-zA-Z_$][a-zA-Z\\d_$]*)*)");

    private final boolean staticIds;

    private SymbolFileSrcJarBuildingVisitor(ZipBuilder zipBuilder, Path root, boolean staticIds) {
      super(zipBuilder, root, null);
      this.staticIds = staticIds;
    }

    private String replaceIdsWithStaticIds(String contents) {
      Matcher packageMatcher = PACKAGE_PATTERN.matcher(contents);
      if (!packageMatcher.find()) {
        return contents;
      }
      String pkg = packageMatcher.group(1);
      StringBuffer out = new StringBuffer();
      Matcher innerClassMatcher = INNER_CLASS.matcher(contents);
      while (innerClassMatcher.find()) {
        String resourceType = innerClassMatcher.group(1);
        Matcher idMatcher = ID_PATTERN.matcher(innerClassMatcher.group(2));
        StringBuffer resourceIds = new StringBuffer();
        while (idMatcher.find()) {
          String javaId = idMatcher.group(1);
          idMatcher.appendReplacement(
              resourceIds,
              String.format(
                  "public static int %s=0x%08X;", javaId, Objects.hash(pkg, resourceType, javaId)));
        }
        idMatcher.appendTail(resourceIds);
        innerClassMatcher.appendReplacement(
            out,
            String.format("public static class %s {%s}", resourceType, resourceIds.toString()));
      }
      innerClassMatcher.appendTail(out);
      return out.toString();
    }

    @Override
    protected void writeEntry(Path file) throws IOException {
      if (file.getFileName().endsWith("R.java")) {
        byte[] content = Files.readAllBytes(file);
        if (staticIds) {
          content =
              replaceIdsWithStaticIds(UTF_8.decode(ByteBuffer.wrap(content)).toString())
                  .getBytes(UTF_8);
        }
        addEntry(file, content);
      }
    }
  }

  /** A FileVisitor that will add all files and dirents to be stored in a zip archive. */
  static final class ZipBuilderVisitorWithDirectories extends ZipBuilderVisitor {
    ZipBuilderVisitorWithDirectories(ZipBuilder zipBuilder, Path root, String directory) {
      super(zipBuilder, root, directory);
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
      paths.add(dir);
      return FileVisitResult.CONTINUE;
    }
  }

  /** A FileVisitor that will add all files to be stored in a zip archive. */
  static class ZipBuilderVisitor extends SimpleFileVisitor<Path> {

    protected final String directoryPrefix;
    protected final Collection<Path> paths = new ArrayList<>();
    protected final Path root;
    private int storageMethod = ZipEntry.STORED;
    private ZipBuilder zipBuilder;

    ZipBuilderVisitor(ZipBuilder zipBuilder, Path root, String directory) {
      this.root = root;
      this.directoryPrefix = directory != null ? (directory + File.separator) : "";
      this.zipBuilder = zipBuilder;
    }

    protected void addEntry(Path file, byte[] content) throws IOException {
      Preconditions.checkArgument(file.startsWith(root), "%s does not start with %s", file, root);
      zipBuilder.addEntry(directoryPrefix + root.relativize(file), content, storageMethod);
    }

    protected void addEntry(String entry, byte[] content) throws IOException {
      zipBuilder.addEntry(entry, content, storageMethod);
    }

    protected void addDirEntry(Path file) throws IOException {
      Preconditions.checkArgument(file.startsWith(root), "%s does not start with %s", file, root);
      String entryName = directoryPrefix + root.relativize(file);
      if (!entryName.endsWith("/")) {
        entryName += "/";
      }
      zipBuilder.addEntry(entryName, new byte[0], storageMethod);
    }

    public void setCompress(boolean compress) {
      storageMethod = compress ? ZipEntry.DEFLATED : ZipEntry.STORED;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      paths.add(file);
      return FileVisitResult.CONTINUE;
    }

    /**
     * Iterate through collected file paths in a deterministic order and write to the zip.
     *
     * @throws IOException if there is an error reading from the source or writing to the zip.
     */
    void writeEntries() throws IOException {
      for (Path path : Ordering.natural().immutableSortedCopy(paths)) {
        writeEntry(path);
      }
    }

    protected void writeEntry(Path file) throws IOException {
      if (Files.isDirectory(file)) {
        addDirEntry(file);
      } else {
        byte[] content = Files.readAllBytes(file);
        addEntry(file, content);
      }
    }
  }

  static final Pattern HEX_REGEX = Pattern.compile("0x[0-9A-Fa-f]{8}");

  /**
   * Copies the AndroidManifest.xml to the specified output location.
   *
   * @param provider The MergedAndroidData which contains the manifest to be written to manifestOut.
   * @param manifestOut The Path to write the AndroidManifest.xml.
   */
  public static void copyManifestToOutput(ManifestContainer provider, Path manifestOut) {
    try {
      Files.createDirectories(manifestOut.getParent());
      Files.copy(provider.getManifest(), manifestOut);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Copies the R.txt to the expected place.
   *
   * @param generatedSourceRoot The path to the generated R.txt.
   * @param rOutput The Path to write the R.txt.
   * @param staticIds Boolean that indicates if the ids should be set to 0x1 for caching purposes.
   */
  public static void copyRToOutput(Path generatedSourceRoot, Path rOutput, boolean staticIds) {
    try {
      Files.createDirectories(rOutput.getParent());
      final Path source = generatedSourceRoot.resolve("R.txt");
      if (Files.exists(source)) {
        if (staticIds) {
          String contents =
              HEX_REGEX
                  .matcher(Joiner.on("\n").join(Files.readAllLines(source, UTF_8)))
                  .replaceAll("0x1");
          Files.write(rOutput, contents.getBytes(UTF_8));
        } else {
          Files.copy(source, rOutput);
        }
      } else {
        // The R.txt wasn't generated, create one for future inheritance, as Bazel always requires
        // outputs. This state occurs when there are no resource directories.
        Files.createFile(rOutput);
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  /** Creates a zip archive from all found R.class (and inner class) files. */
  public static void createClassJar(
      Path generatedClassesRoot,
      Path classJar,
      @Nullable String targetLabel,
      @Nullable String injectingRuleKind) {
    try {
      Files.createDirectories(classJar.getParent());
      try (final ZipBuilder zip = ZipBuilder.createFor(classJar)) {
        ClassJarBuildingVisitor visitor = new ClassJarBuildingVisitor(zip, generatedClassesRoot);
        Files.walkFileTree(generatedClassesRoot, visitor);
        visitor.writeManifestContent(targetLabel, injectingRuleKind);
        visitor.writeEntries();
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  /** Creates a zip archive from all files under the provided root. */
  public static void archiveDirectory(Path root, Path archive) {
    try {
      Files.createDirectories(archive.getParent());
      try (final ZipBuilder zip = ZipBuilder.createFor(archive)) {
        ZipBuilderVisitor visitor = new ZipBuilderVisitor(zip, root, null);
        visitor.setCompress(false);
        Files.walkFileTree(root, visitor);
        visitor.writeEntries();
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  /** Creates a zip archive from all found R.java files. */
  public static void createSrcJar(Path generatedSourcesRoot, Path srcJar, boolean staticIds) {
    try {
      Files.createDirectories(srcJar.getParent());
      try (final ZipBuilder zip = ZipBuilder.createFor(srcJar)) {
        SymbolFileSrcJarBuildingVisitor visitor =
            new SymbolFileSrcJarBuildingVisitor(zip, generatedSourcesRoot, staticIds);
        Files.walkFileTree(generatedSourcesRoot, visitor);
        visitor.writeEntries();
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  /** Collects all the compiled resources into an archive, normalizing the paths to the root. */
  public static Path archiveCompiledResources(
      final Path archiveOut,
      final Path databindingResourcesRoot,
      final Path compiledRoot,
      final List<Path> compiledArtifacts)
      throws IOException {
    final Path relativeDatabindingProcessedResources =
        databindingResourcesRoot.getRoot().relativize(databindingResourcesRoot);

    try (ZipBuilder builder = ZipBuilder.createFor(archiveOut)) {
      for (Path artifact : compiledArtifacts) {
        Path relativeName = artifact;

        // remove compiled resources prefix
        if (artifact.startsWith(compiledRoot)) {
          relativeName = compiledRoot.relativize(relativeName);
        }
        // remove databinding prefix
        if (relativeName.startsWith(relativeDatabindingProcessedResources)) {
          relativeName =
              relativeName.subpath(
                  relativeDatabindingProcessedResources.getNameCount(),
                  relativeName.getNameCount());
        }

        builder.addEntry(
            relativeName.toString(),
            Files.readAllBytes(artifact),
            ZipEntry.STORED,
            ResourceCompiler.getCompiledType(relativeName.toString()).asComment());
      }
    }
    return archiveOut;
  }
}
