// 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) {
    if (type == null) {
      return null;
    }
    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
        + ")";
  }
}
