// 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.graph.LazyLoadedDexApplication.AllClasses;
import com.android.tools.r8.naming.ClassNameMapper;
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.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class DirectMappedDexApplication extends DexApplication {

  private final AllClasses allClasses;
  private final ImmutableMap<DexType, DexLibraryClass> libraryClasses;

  private DirectMappedDexApplication(ClassNameMapper proguardMap,
      AllClasses allClasses,
      ProgramClassCollection programClasses,
      ImmutableList<ProgramResourceProvider> programResourceProviders,
      ImmutableMap<DexType, DexLibraryClass> libraryClasses,
      ImmutableSet<DexType> mainDexList, String deadCode,
      DexItemFactory dexItemFactory, DexString highestSortingString,
      Timing timing) {
    super(proguardMap, programClasses, programResourceProviders, mainDexList, deadCode,
        dexItemFactory, highestSortingString, timing);
    this.allClasses = allClasses;
    this.libraryClasses = libraryClasses;
  }

  public Collection<DexLibraryClass> libraryClasses() {
    return libraryClasses.values();
  }

  @Override
  public DexClass definitionFor(DexType type) {
    DexClass result = programClasses.get(type);
    if (result == null) {
      result = libraryClasses.get(type);
    }
    return result;
  }

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

  @Override
  public DirectMappedDexApplication toDirect() {
    return this;
  }

  @Override
  public DirectMappedDexApplication asDirect() {
    return this;
  }

  @Override
  public String toString() {
    return "DexApplication (direct)";
  }

  public DirectMappedDexApplication rewrittenWithLense(GraphLense graphLense) {
    assert mappingIsValid(graphLense, programClasses.getAllTypes());
    assert mappingIsValid(graphLense, libraryClasses.keySet());
    // As a side effect, this will rebuild the program classes and library classes maps.
    return this.builder().build().asDirect();
  }

  private boolean mappingIsValid(GraphLense graphLense, Iterable<DexType> types) {
    // The lense might either map to a different type that is already present in the application
    // (e.g. relinking a type) or it might encode a type that was renamed, in which case the
    // original type will point to a definition that was renamed.
    for (DexType type : types) {
      DexType renamed = graphLense.lookupType(type);
      if (renamed != type) {
        if (definitionFor(type).type != renamed && definitionFor(renamed) == null) {
          return false;
        }
      }
    }
    return true;
  }

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

    private final AllClasses allClasses;
    private final List<DexLibraryClass> libraryClasses = new ArrayList<>();

    Builder(LazyLoadedDexApplication application) {
      super(application);
      // As a side-effect, this will force-load all classes.
      this.allClasses = application.loadAllClasses();
      Map<DexType, DexClass> allClasses = this.allClasses.getClasses();
      // TODO(120884788): This filter will only add library classes which are not program classes.
      Iterables.filter(allClasses.values(), DexLibraryClass.class).forEach(libraryClasses::add);
    }

    private Builder(DirectMappedDexApplication application) {
      super(application);
      this.allClasses = application.allClasses;
      this.libraryClasses.addAll(application.libraryClasses.values());
    }

    @Override
    Builder self() {
      return this;
    }

    @Override
    public DexApplication build() {
      // Rebuild the map. This will fail if keys are not unique.
      return new DirectMappedDexApplication(
          proguardMap,
          allClasses,
          ProgramClassCollection.create(
              programClasses, ProgramClassCollection::resolveClassConflictImpl),
          ImmutableList.copyOf(programResourceProviders),
          libraryClasses.stream().collect(ImmutableMap.toImmutableMap(c -> c.type, c -> c)),
          ImmutableSet.copyOf(mainDexList),
          deadCode,
          dexItemFactory,
          highestSortingString,
          timing);
    }
  }
}
