// 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.keepanno.annotations.KeepForApi;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.StreamUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Set;

/**
 * Represents program application resources.
 *
 * <p>The content kind or format of a program resource can be either a Java class-file or an Android
 * DEX file. In both cases, the resource must be able to provide the content as a byte stream. A
 * resource may optionally include a set describing the class descriptors for each type that is
 * defined by the resource.
 */
@KeepForApi
public interface ProgramResource extends Resource {

  /** Type of program-format kinds. */
  @KeepForApi
  enum Kind {
    /** Format-kind for Java class-file resources. */
    CF,
    /** Format-kind for Android dex-file resources. */
    DEX,
  }

  /**
   * Create a program resource for a given file.
   *
   * <p>The origin of a file resource is the path of the file.
   */
  static ProgramResource fromFile(Kind kind, Path file) {
    return new FileResource(kind, file, null);
  }

  /**
   * Create a program resource for a given type, content and type descriptor.
   *
   * <p>The origin must be supplied upon construction. If no reasonable origin
   * exits, use {@code Origin.unknown()}.
   */
  static ProgramResource fromBytes(
      Origin origin, Kind kind, byte[] bytes, Set<String> typeDescriptors) {
    return new ByteResource(origin, kind, bytes, typeDescriptors);
  }

  /** Get the program format-kind of the resource. */
  Kind getKind();

  /** Get the bytes of the program resource. */
  InputStream getByteStream() throws ResourceException;

  /** Optional getter to obtain the bytes of the program resource as an array. */
  default byte[] getBytes() throws ResourceException {
    try {
      return StreamUtils.streamToByteArrayClose(getByteStream());
    } catch (IOException e) {
      throw new ResourceException(getOrigin(), e);
    }
  }

  /**
   * Get the set of class descriptors for classes defined by this resource.
   *
   * <p>This is not deprecated and will remain after Resource::getClassDescriptors is removed.
   *
   * @return Set of class descriptors defined by the resource or null if unknown.
   */
  Set<String> getClassDescriptors();

  /** File-based program resource. */
  @KeepForApi
  class FileResource implements ProgramResource {
    private final Origin origin;
    private final Kind kind;
    private final Path file;
    private final Set<String> classDescriptors;

    private FileResource(Kind kind, Path file, Set<String> classDescriptors) {
      this.origin = new PathOrigin(file);
      this.kind = kind;
      this.file = file;
      this.classDescriptors = classDescriptors;
    }

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

    @Override
    public Kind getKind() {
      return kind;
    }

    @Override
    public InputStream getByteStream() throws ResourceException {
      try {
        return Files.newInputStream(file);
      } catch (IOException e) {
        throw new ResourceException(getOrigin(), e);
      }
    }

    @Override
    public byte[] getBytes() throws ResourceException {
      try {
        return Files.readAllBytes(file);
      } catch (IOException e) {
        throw new ResourceException(getOrigin(), e);
      }
    }

    @Override
    public Set<String> getClassDescriptors() {
      return classDescriptors;
    }
  }

  /** Byte-content based program resource. */
  @KeepForApi
  class ByteResource implements ProgramResource {
    private final Origin origin;
    private final Kind kind;
    private final byte[] bytes;
    private final Set<String> classDescriptors;

    private ByteResource(Origin origin, Kind kind, byte[] bytes, Set<String> classDescriptors) {
      assert bytes != null;
      this.origin = origin;
      this.kind = kind;
      this.bytes = bytes;
      this.classDescriptors = classDescriptors;
    }

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

    @Override
    public Kind getKind() {
      return kind;
    }

    @SuppressWarnings("RedundantThrows")
    @Override
    public InputStream getByteStream() throws ResourceException {
      return new ByteArrayInputStream(bytes);
    }

    @SuppressWarnings("RedundantThrows")
    @Override
    public byte[] getBytes() throws ResourceException {
      return bytes;
    }

    @Override
    public Set<String> getClassDescriptors() {
      return classDescriptors;
    }
  }
}
