// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;

import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.keepanno.annotations.KeepForApi;
import com.android.tools.r8.origin.ArchiveEntryOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.BooleanBox;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.ZipUtils;
import com.google.common.io.ByteStreams;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

/** Provider for archives of program resources. */
@KeepForApi
public class ArchiveProgramResourceProvider implements ProgramResourceProvider {

  interface ArchiveEntryConsumer {
    void accept(ArchiveEntryOrigin entry, InputStream stream) throws IOException;
  }

  @KeepForApi
  public interface ZipFileSupplier {
    ZipFile open() throws IOException;
  }

  public static boolean includeClassFileEntries(String entry) {
    return ZipUtils.isClassFile(entry);
  }

  public static boolean includeDexEntries(String entry) {
    return ZipUtils.isDexFile(entry);
  }

  public static boolean includeClassFileOrDexEntries(String entry) {
    return ZipUtils.isClassFile(entry) || ZipUtils.isDexFile(entry);
  }

  private final Origin origin;
  private final ZipFileSupplier supplier;
  private final Predicate<String> include;

  public static ArchiveProgramResourceProvider fromArchive(Path archive) {
    return fromArchive(archive, ArchiveProgramResourceProvider::includeClassFileOrDexEntries);
  }

  public static ArchiveProgramResourceProvider fromArchive(
      Path archive, Predicate<String> include) {
    return fromSupplier(
        new PathOrigin(archive),
        () -> FileUtils.createZipFile(archive.toFile(), StandardCharsets.UTF_8),
        include);
  }

  public static ArchiveProgramResourceProvider fromSupplier(
      Origin origin, ZipFileSupplier supplier) {
    return fromSupplier(
        origin, supplier, ArchiveProgramResourceProvider::includeClassFileOrDexEntries);
  }

  public static ArchiveProgramResourceProvider fromSupplier(
      Origin origin, ZipFileSupplier supplier, Predicate<String> include) {
    return new ArchiveProgramResourceProvider(origin, supplier, include);
  }

  private ArchiveProgramResourceProvider(
      Origin origin, ZipFileSupplier supplier, Predicate<String> include) {
    assert origin != null;
    assert supplier != null;
    assert include != null;
    this.origin = origin;
    this.supplier = supplier;
    this.include = include;
  }

  void readArchive(ArchiveEntryConsumer consumer) throws IOException {
    try (ZipFile zipFile = supplier.open()) {
      final Enumeration<? extends ZipEntry> entries = zipFile.entries();
      while (entries.hasMoreElements()) {
        ZipEntry entry = entries.nextElement();
        try (InputStream stream = zipFile.getInputStream(entry)) {
          consumer.accept(new ArchiveEntryOrigin(entry.getName(), origin), stream);
        }
      }
    } catch (ZipException e) {
      throw new CompilationError("Zip error while reading archive" + e.getMessage(), e, origin);
    }
  }

  @Override
  public Collection<ProgramResource> getProgramResources() throws ResourceException {
    try {
      List<ProgramResource> dexResources = new ArrayList<>();
      List<ProgramResource> classResources = new ArrayList<>();
      readArchive(
          (entry, stream) -> {
            String name = entry.getEntryName();
            if (include.test(name)) {
              if (ZipUtils.isDexFile(name)) {
                dexResources.add(
                    ProgramResource.fromBytes(
                        entry, Kind.DEX, ByteStreams.toByteArray(stream), null));
              } else if (ZipUtils.isClassFile(name)) {
                String descriptor = DescriptorUtils.guessTypeDescriptor(name);
                classResources.add(
                    ProgramResource.fromBytes(
                        entry,
                        Kind.CF,
                        ByteStreams.toByteArray(stream),
                        Collections.singleton(descriptor)));
              }
            }
          });
      if (!dexResources.isEmpty() && !classResources.isEmpty()) {
        throw new CompilationError(
            "Cannot create android app from an archive containing both DEX and Java-bytecode "
                + "content.",
            origin);
      }
      return !dexResources.isEmpty() ? dexResources : classResources;
    } catch (IOException e) {
      throw new ResourceException(origin, e);
    }
  }

  @Override
  public void getProgramResources(Consumer<ProgramResource> consumer) throws ResourceException {
    try {
      BooleanBox seenCf = new BooleanBox();
      BooleanBox seenDex = new BooleanBox();
      readArchive(
          (entry, stream) -> {
            String name = entry.getEntryName();
            if (include.test(name)) {
              if (ZipUtils.isDexFile(name)) {
                consumer.accept(
                    ProgramResource.fromBytes(
                        entry, Kind.DEX, ByteStreams.toByteArray(stream), null));
                seenDex.set();
              } else if (ZipUtils.isClassFile(name)) {
                String descriptor = DescriptorUtils.guessTypeDescriptor(name);
                consumer.accept(
                    ProgramResource.fromBytes(
                        entry,
                        Kind.CF,
                        ByteStreams.toByteArray(stream),
                        Collections.singleton(descriptor)));
                seenCf.set();
              }
            }
          });
      if (seenCf.isTrue() && seenDex.isTrue()) {
        throw new CompilationError(
            "Cannot create android app from an archive containing both DEX and Java-bytecode "
                + "content.",
            origin);
      }
    } catch (IOException e) {
      throw new ResourceException(origin, e);
    }
  }
}
