// 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.
// Copyright (c) 2016, 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.graph;

import com.android.tools.r8.ProgramResourceProvider;
import com.android.tools.r8.dex.ApplicationReader.ProgramClassConflictResolver;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.utils.ClasspathClassCollection;
import com.android.tools.r8.utils.LibraryClassCollection;
import com.android.tools.r8.utils.ProgramClassCollection;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.IdentityHashMap;
import java.util.Map;

public class LazyLoadedDexApplication extends DexApplication {

  private final ClasspathClassCollection classpathClasses;
  private final LibraryClassCollection libraryClasses;

  /**
   * Constructor should only be invoked by the DexApplication.Builder.
   */
  private LazyLoadedDexApplication(ClassNameMapper proguardMap,
      ProgramClassCollection programClasses,
      ImmutableList<ProgramResourceProvider> programResourceProviders,
      ClasspathClassCollection classpathClasses,
      LibraryClassCollection libraryClasses,
      ImmutableSet<DexType> mainDexList, String deadCode,
      DexItemFactory dexItemFactory, DexString highestSortingString,
      Timing timing) {
    super(proguardMap, programClasses, programResourceProviders, mainDexList, deadCode,
        dexItemFactory, highestSortingString, timing);
    this.classpathClasses = classpathClasses;
    this.libraryClasses = libraryClasses;
  }

  @Override
  public DexClass definitionFor(DexType type) {
    assert type.isClassType() : "Cannot lookup definition for type: " + type;
    DexClass clazz = programClasses.get(type);
    if (clazz == null && classpathClasses != null) {
      clazz = classpathClasses.get(type);
    }
    if (clazz == null && libraryClasses != null) {
      clazz = libraryClasses.get(type);
    }
    return clazz;
  }

  static class AllClasses {
    private Map<DexType, DexClass> libraryClasses;
    private Map<DexType, DexClass> classpathClasses;
    private Map<DexType, DexClass> programClasses;
    private Map<DexType, DexClass> classes;

    AllClasses(
        LibraryClassCollection libraryClasses,
        ClasspathClassCollection classpathClasses,
        ProgramClassCollection programClasses) {
      load(libraryClasses, classpathClasses, programClasses);

      // Collect loaded classes in the precedence order program classes, class path classes and
      // library classes.
      // TODO(b/120884788): Change this.
      classes = new IdentityHashMap<>();
      classes.putAll(this.programClasses);
      if (classpathClasses != null) {
        classpathClasses.getAllClasses().forEach(clazz -> classes.putIfAbsent(clazz.type, clazz));
      }
      if (libraryClasses != null) {
        libraryClasses.getAllClasses().forEach(clazz -> classes.putIfAbsent(clazz.type, clazz));
      }
    }

    public Map<DexType, DexClass> getLibraryClasses() {
      return libraryClasses;
    }

    public Map<DexType, DexClass> getClasspathClasses() {
      return classpathClasses;
    }

    public Map<DexType, DexClass> getClasses() {
      return classes;
    }

    private void load(
        LibraryClassCollection libraryClasses,
        ClasspathClassCollection classpathClasses,
        ProgramClassCollection programClasses) {
      if (libraryClasses != null) {
        libraryClasses.forceLoad(type -> true);
        this.libraryClasses = libraryClasses.getAllClassesInMap();
      }
      if (classpathClasses != null) {
        classpathClasses.forceLoad(type -> true);
        this.classpathClasses = classpathClasses.getAllClassesInMap();
      }
      assert programClasses != null;
      // Program classes are supposed to be loaded, but force-loading them is no-op.
      programClasses.forceLoad(type -> true);
      this.programClasses = programClasses.getAllClassesInMap();
    }
  }

  /**
   * Force load all classes and return type -> class map containing all the classes.
   */
  public AllClasses loadAllClasses() {
    return new AllClasses(libraryClasses, classpathClasses, programClasses);
  }

  public static class Builder extends DexApplication.Builder<Builder> {

    private ClasspathClassCollection classpathClasses;
    private LibraryClassCollection libraryClasses;
    private final ProgramClassConflictResolver resolver;

    Builder(ProgramClassConflictResolver resolver, DexItemFactory dexItemFactory, Timing timing) {
      super(dexItemFactory, timing);
      this.resolver = resolver;
      this.classpathClasses = null;
      this.libraryClasses = null;
    }

    private Builder(LazyLoadedDexApplication application) {
      super(application);
      this.resolver = ProgramClassCollection::resolveClassConflictImpl;
      this.classpathClasses = application.classpathClasses;
      this.libraryClasses = application.libraryClasses;
    }

    @Override
    Builder self() {
      return this;
    }

    public Builder setClasspathClassCollection(ClasspathClassCollection classes) {
      this.classpathClasses = classes;
      return this;
    }

    public Builder setLibraryClassCollection(LibraryClassCollection classes) {
      this.libraryClasses = classes;
      return this;
    }

    @Override
    public LazyLoadedDexApplication build() {
      return new LazyLoadedDexApplication(
          proguardMap,
          ProgramClassCollection.create(programClasses, resolver),
          ImmutableList.copyOf(programResourceProviders),
          classpathClasses,
          libraryClasses,
          ImmutableSet.copyOf(mainDexList),
          deadCode,
          dexItemFactory,
          highestSortingString,
          timing);
    }
  }

  @Override
  public Builder builder() {
    return new Builder(this);
  }

  @Override
  public DirectMappedDexApplication toDirect() {
    return new DirectMappedDexApplication.Builder(this).build().asDirect();
  }

  @Override
  public String toString() {
    return "Application (" + programClasses + "; " + classpathClasses + "; " + libraryClasses
        + ")";
  }
}
