// 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.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.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);
    }
  }
}
