// Copyright (c) 2018, 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.CLASS_EXTENSION;
import static com.android.tools.r8.utils.FileUtils.isArchive;

import com.android.tools.r8.ClassFileResourceProvider;
import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.origin.ArchiveEntryOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * Internal-only provider for providing class files when clients use the addClasspathFiles and
 * addLibraryFiles API.
 *
 * <p>The purpose of the internal provider is that for the API use above we know it is safe to use
 * the zip-file descriptor throughout compilation and close at the end of reading. It must also be
 * safe to reopen it as currently our own tests reuse AndroidApp structures.
 */
class InternalArchiveClassFileProvider implements ClassFileResourceProvider, AutoCloseable {
  private final Path path;
  private final Origin origin;
  private final Set<String> descriptors = new HashSet<>();

  private ZipFile openedZipFile = null;

  /**
   * Creates a lazy class-file program-resource provider.
   *
   * @param archive Zip archive to provide resources from.
   */
  public InternalArchiveClassFileProvider(Path archive) throws IOException {
    this(archive, entry -> true);
  }

  /**
   * Creates a lazy class-file program-resource provider with an include filter.
   *
   * @param archive Zip archive to provide resources from.
   * @param include Predicate deciding if a given class-file entry should be provided.
   */
  public InternalArchiveClassFileProvider(Path archive, Predicate<String> include)
      throws IOException {
    assert isArchive(archive);
    path = archive;
    origin = new PathOrigin(archive);
    final Enumeration<? extends ZipEntry> entries = getOpenZipFile().entries();
    while (entries.hasMoreElements()) {
      ZipEntry entry = entries.nextElement();
      String name = entry.getName();
      if (ZipUtils.isClassFile(name) && include.test(name)) {
        descriptors.add(DescriptorUtils.guessTypeDescriptor(name));
      }
    }
  }

  @Override
  public Set<String> getClassDescriptors() {
    return Collections.unmodifiableSet(descriptors);
  }

  @Override
  public ProgramResource getProgramResource(String descriptor) {
    if (!descriptors.contains(descriptor)) {
      return null;
    }
    return new ProgramResource() {

      private final Origin entryOrigin =
          new ArchiveEntryOrigin(getZipEntryNameFromDescriptor(descriptor), origin);

      @Override
      public Origin getOrigin() {
        return entryOrigin;
      }

      @Override
      public Kind getKind() {
        return Kind.CF;
      }

      @Override
      public Set<String> getClassDescriptors() {
        return Collections.singleton(descriptor);
      }

      @Override
      public InputStream getByteStream() throws ResourceException {
        try {
          ZipEntry zipEntry = getZipEntryFromDescriptor(descriptor);
          return getOpenZipFile().getInputStream(zipEntry);
        } catch (IOException e) {
          throw new ResourceException(getOrigin(), "Failed to read '" + descriptor + "'");
        }
      }
    };
  }

  private ZipFile getOpenZipFile() throws IOException {
    if (openedZipFile == null) {
      try {
        openedZipFile = FileUtils.createZipFile(path.toFile(), StandardCharsets.UTF_8);
      } catch (IOException e) {
        if (!Files.exists(path)) {
          throw new NoSuchFileException(path.toString());
        } else {
          throw e;
        }
      }
    }
    return openedZipFile;
  }

  @Override
  public void close() throws IOException {
    openedZipFile.close();
    openedZipFile = null;
  }

  private static String getZipEntryNameFromDescriptor(String descriptor) {
    return descriptor.substring(1, descriptor.length() - 1) + CLASS_EXTENSION;
  }

  private ZipEntry getZipEntryFromDescriptor(String descriptor) throws IOException {
    return getOpenZipFile().getEntry(getZipEntryNameFromDescriptor(descriptor));
  }
}
