// 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 com.android.tools.r8.ClassFileResourceProvider;
import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.ClassKind;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.JarApplicationReader;
import com.android.tools.r8.graph.JarClassFileReader;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;

/** Represents a provider for classes loaded from different sources. */
public abstract class ClassProvider<T extends DexClass> {
  private final ClassKind<T> classKind;

  ClassProvider(ClassKind<T> classKind) {
    this.classKind = classKind;
  }

  /** The kind of the classes created by the provider. */
  final ClassKind<T> getClassKind() {
    return classKind;
  }

  /**
   * The provider uses the callback to return all the classes that might
   * be associated with the descriptor asked for.
   *
   * NOTE: the provider is not required to cache created classes and this
   * method may create a new class instance in case it is called twice for
   * the same type. For this reason it is recommended that the provider
   * user only calls this method once per any given type.
   *
   * NOTE: thread-safe.
   */
  public abstract void collectClass(DexType type, Consumer<T> classConsumer);

  /**
   * Returns all the types of classes that might be produced by this provider.
   *
   * NOTE: thread-safe.
   */
  public abstract Collection<DexType> collectTypes();

  /** Create class provider for java class resource provider. */
  public static <T extends DexClass> ClassProvider<T> forClassFileResources(
      ClassKind<T> classKind, ClassFileResourceProvider provider, JarApplicationReader reader) {
    return new ClassFileResourceReader<>(classKind, provider, reader);
  }

  /** Create class provider for preloaded classes, classes may have conflicting names. */
  public static <T extends DexClass> ClassProvider<T> forPreloadedClasses(
      ClassKind<T> classKind, Collection<T> classes) {
    ImmutableListMultimap.Builder<DexType, T> builder = ImmutableListMultimap.builder();
    for (T clazz : classes) {
      builder.put(clazz.type, clazz);
    }
    return new PreloadedClassProvider<>(classKind, builder.build());
  }

  /** Create class provider for preloaded classes. */
  public static <T extends DexClass> ClassProvider<T> combine(
      ClassKind<T> classKind, List<ClassProvider<T>> providers) {
    return new CombinedClassProvider<>(classKind, providers);
  }

  private static class ClassFileResourceReader<T extends DexClass> extends ClassProvider<T> {
    private final ClassKind<T> classKind;
    private final ClassFileResourceProvider provider;
    private final JarApplicationReader reader;

    private ClassFileResourceReader(
        ClassKind<T> classKind, ClassFileResourceProvider provider, JarApplicationReader reader) {
      super(classKind);
      this.classKind = classKind;
      this.provider = provider;
      this.reader = reader;
    }

    @Override
    public void collectClass(DexType type, Consumer<T> classConsumer) {
      String descriptor = type.descriptor.toString();
      ProgramResource resource = provider.getProgramResource(descriptor);
      if (resource != null) {
        try {
          JarClassFileReader<T> classReader =
              new JarClassFileReader<>(reader, classConsumer, classKind);
          classReader.read(resource);
        } catch (ResourceException e) {
          throw new CompilationError("Failed to load class: " + descriptor, e);
        }
      }
    }

    @Override
    public Collection<DexType> collectTypes() {
      List<DexType> types = new ArrayList<>();
      for (String descriptor : provider.getClassDescriptors()) {
        types.add(reader.options.itemFactory.createType(descriptor));
      }
      return types;
    }

    @Override
    public String toString() {
      return "class-resource-provider(" + provider.toString() + ")";
    }
  }

  private static class PreloadedClassProvider<T extends DexClass> extends ClassProvider<T> {
    private final Multimap<DexType, T> classes;

    private PreloadedClassProvider(ClassKind<T> classKind, Multimap<DexType, T> classes) {
      super(classKind);
      this.classes = classes;
    }

    @Override
    public void collectClass(DexType type, Consumer<T> classConsumer) {
      for (T clazz : classes.get(type)) {
        classConsumer.accept(clazz);
      }
    }

    @Override
    public Collection<DexType> collectTypes() {
      return classes.keys();
    }

    @Override
    public String toString() {
      return "preloaded(" + classes.size() + ")";
    }
  }

  private static class CombinedClassProvider<T extends DexClass> extends ClassProvider<T> {
    private final List<ClassProvider<T>> providers;

    private CombinedClassProvider(ClassKind<T> classKind, List<ClassProvider<T>> providers) {
      super(classKind);
      this.providers = providers;
    }

    @Override
    public void collectClass(DexType type, Consumer<T> classConsumer) {
      for (ClassProvider<T> provider : providers) {
        provider.collectClass(type, classConsumer);
      }
    }

    @Override
    public Collection<DexType> collectTypes() {
      Set<DexType> types = Sets.newIdentityHashSet();
      for (ClassProvider<T> provider : providers) {
        types.addAll(provider.collectTypes());
      }
      return types;
    }

    @Override
    public String toString() {
      StringBuilder builder = new StringBuilder();
      String prefix = "combined(";
      for (ClassProvider<T> provider : providers) {
        builder.append(prefix);
        prefix = ", ";
        builder.append(provider);
      }
      return builder.append(")").toString();
    }
  }
}
