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

import static com.android.tools.r8.utils.FileUtils.isArchive;

import com.android.tools.r8.DataDirectoryResource;
import com.android.tools.r8.DataEntryResource;
import com.android.tools.r8.DataResourceProvider;
import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.ProgramResourceProvider;
import com.android.tools.r8.ResourceException;
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.shaking.FilteredClassPath;
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.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

@KeepForApi
public class ArchiveResourceProvider implements ProgramResourceProvider, DataResourceProvider {

  private final Origin origin;
  private final FilteredClassPath archive;
  private final boolean ignoreDexInArchive;

  public static ArchiveResourceProvider fromArchive(Path archive, boolean ignoreDexInArchive) {
    return new ArchiveResourceProvider(FilteredClassPath.unfiltered(archive), ignoreDexInArchive);
  }

  ArchiveResourceProvider(FilteredClassPath archive, boolean ignoreDexInArchive) {
    assert isArchive(archive.getPath());
    origin = new PathOrigin(archive.getPath());
    this.archive = archive;
    this.ignoreDexInArchive = ignoreDexInArchive;
  }

  public Origin getOrigin() {
    return origin;
  }

  private List<ProgramResource> readArchive() throws IOException {
    List<ProgramResource> dexResources = new ArrayList<>();
    List<ProgramResource> classResources = new ArrayList<>();
    try (ZipFile zipFile =
        FileUtils.createZipFile(archive.getPath().toFile(), StandardCharsets.UTF_8)) {
      final Enumeration<? extends ZipEntry> entries = zipFile.entries();
      while (entries.hasMoreElements()) {
        ZipEntry entry = entries.nextElement();
        try (InputStream stream = zipFile.getInputStream(entry)) {
          String name = entry.getName();
          Origin entryOrigin = new ArchiveEntryOrigin(name, origin);
          if (archive.matchesFile(name)) {
            if (ZipUtils.isDexFile(name)) {
              if (!ignoreDexInArchive) {
                ProgramResource resource =
                    OneShotByteResource.create(
                        Kind.DEX, entryOrigin, ByteStreams.toByteArray(stream), null);
                dexResources.add(resource);
              }
            } else if (ZipUtils.isClassFile(name)) {
              String descriptor = DescriptorUtils.guessTypeDescriptor(name);
              ProgramResource resource =
                  OneShotByteResource.create(
                      Kind.CF,
                      entryOrigin,
                      ByteStreams.toByteArray(stream),
                      Collections.singleton(descriptor));
              classResources.add(resource);
            }
          }
        }
      }
    } catch (ZipException e) {
      throw new CompilationError(
          "Zip error while reading '" + archive + "': " + e.getMessage(), e);
    }
    if (!dexResources.isEmpty() && !classResources.isEmpty()) {
      throw new CompilationError(
          "Cannot create android app from an archive '"
              + archive
              + "' containing both DEX and Java-bytecode content",
          origin);
    }
    return !dexResources.isEmpty() ? dexResources : classResources;
  }

  @Override
  public Collection<ProgramResource> getProgramResources() throws ResourceException {
    try {
      return readArchive();
    } catch (IOException e) {
      throw new ResourceException(origin, e);
    }
  }

  @Override
  public DataResourceProvider getDataResourceProvider() {
    return this;
  }

  @Override
  public void accept(Visitor resourceBrowser) throws ResourceException {
    try (ZipFile zipFile =
        FileUtils.createZipFile(archive.getPath().toFile(), StandardCharsets.UTF_8)) {
      final Enumeration<? extends ZipEntry> entries = zipFile.entries();
      while (entries.hasMoreElements()) {
        ZipEntry entry = entries.nextElement();
        String name = entry.getName();
        if (archive.matchesFile(name) && !isProgramResourceName(name)) {
          if (entry.isDirectory()) {
            resourceBrowser.visit(DataDirectoryResource.fromZip(zipFile, entry));
          } else {
            resourceBrowser.visit(DataEntryResource.fromZip(zipFile, entry));
          }
        }
      }
    } catch (ZipException e) {
      throw new ResourceException(origin, new CompilationError(
          "Zip error while reading '" + archive + "': " + e.getMessage(), e));
    } catch (IOException e) {
      throw new ResourceException(origin, new CompilationError(
          "I/O exception while reading '" + archive + "': " + e.getMessage(), e));
    }
  }

  private boolean isProgramResourceName(String name) {
    return ZipUtils.isClassFile(name) || (ZipUtils.isDexFile(name) && !ignoreDexInArchive);
  }

  public void accept(Consumer<ProgramResource> visitor) throws ResourceException {
    try (ZipFile zipFile =
        FileUtils.createZipFile(archive.getPath().toFile(), StandardCharsets.UTF_8)) {
      final Enumeration<? extends ZipEntry> entries = zipFile.entries();
      while (entries.hasMoreElements()) {
        ZipEntry entry = entries.nextElement();
        String name = entry.getName();
        if (archive.matchesFile(name) && isProgramResourceName(name)) {
          Origin entryOrigin = new ArchiveEntryOrigin(name, origin);
          try (InputStream stream = zipFile.getInputStream(entry)) {
            if (ZipUtils.isDexFile(name)) {
              OneShotByteResource resource =
                  OneShotByteResource.create(
                      Kind.DEX, entryOrigin, ByteStreams.toByteArray(stream), null);
              visitor.accept(resource);
            } else if (ZipUtils.isClassFile(name)) {
              OneShotByteResource resource =
                  OneShotByteResource.create(
                      Kind.CF,
                      entryOrigin,
                      ByteStreams.toByteArray(stream),
                      Collections.singleton(DescriptorUtils.guessTypeDescriptor(name)));
              visitor.accept(resource);
            }
          }
        }
      }
    } catch (ZipException e) {
      throw new ResourceException(
          origin,
          new CompilationError("Zip error while reading '" + archive + "': " + e.getMessage(), e));
    } catch (IOException e) {
      throw new ResourceException(
          origin,
          new CompilationError(
              "I/O exception while reading '" + archive + "': " + e.getMessage(), e));
    }
  }
}
