// Copyright (c) 2020, 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.ir.desugar;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GenericSignature;
import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DesugaredLibraryEmulatedInterfaceDuplicator {

  final AppView<?> appView;
  final Map<DexType, DexType> emulatedInterfaces;

  public DesugaredLibraryEmulatedInterfaceDuplicator(AppView<?> appView) {
    this.appView = appView;
    emulatedInterfaces =
        appView.options().desugaredLibraryConfiguration.getEmulateLibraryInterface();
  }

  public void duplicateEmulatedInterfaces() {
    // All classes implementing an emulated interface now implements the interface and the
    // emulated one, as well as hidden overrides, for correct emulated dispatch.
    // We not that duplicated interfaces won't feature the correct type parameters in the
    // class signature since such signature is expected to be unused.
    for (DexProgramClass clazz : appView.appInfo().classes()) {
      if (clazz.type == appView.dexItemFactory().objectType) {
        continue;
      }
      if (emulatedInterfaces.containsKey(clazz.type)) {
        transformEmulatedInterfaces(clazz);
      } else {
        duplicateEmulatedInterfaces(clazz);
      }
    }
  }

  private void transformEmulatedInterfaces(DexProgramClass clazz) {
    List<ClassTypeSignature> newInterfaces = new ArrayList<>();
    GenericSignature.ClassSignature classSignature = clazz.getClassSignature(appView);
    for (int i = 0; i < clazz.interfaces.size(); i++) {
      DexType itf = clazz.interfaces.values[i];
      assert emulatedInterfaces.containsKey(itf);
      List<FieldTypeSignature> typeArguments;
      if (classSignature.hasNoSignature()) {
        typeArguments = Collections.emptyList();
      } else {
        ClassTypeSignature classTypeSignature = classSignature.superInterfaceSignatures().get(i);
        assert itf == classTypeSignature.type();
        typeArguments = classTypeSignature.typeArguments();
      }
      newInterfaces.add(new ClassTypeSignature(emulatedInterfaces.get(itf), typeArguments));
    }
    clazz.replaceInterfaces(newInterfaces, appView);
  }

  private void duplicateEmulatedInterfaces(DexProgramClass clazz) {
    List<DexType> extraInterfaces = new ArrayList<>();
    LinkedList<DexClass> workList = new LinkedList<>();
    Set<DexType> processed = Sets.newIdentityHashSet();
    workList.add(clazz);
    while (!workList.isEmpty()) {
      DexClass dexClass = workList.removeFirst();
      if (processed.contains(dexClass.type)) {
        continue;
      }
      processed.add(dexClass.type);
      if (dexClass.superType != appView.dexItemFactory().objectType) {
        processSuperType(clazz.superType, extraInterfaces, workList);
      }
      for (DexType itf : dexClass.interfaces.values) {
        processSuperType(itf, extraInterfaces, workList);
      }
    }
    extraInterfaces = removeDuplicates(extraInterfaces);
    List<ClassTypeSignature> extraInterfaceSignatures = new ArrayList<>();
    for (DexType extraInterface : extraInterfaces) {
      extraInterfaceSignatures.add(new ClassTypeSignature(extraInterface));
    }
    clazz.addExtraInterfaces(extraInterfaceSignatures, appView);
  }

  private List<DexType> removeDuplicates(List<DexType> extraInterfaces) {
    if (extraInterfaces.size() <= 1) {
      return extraInterfaces;
    }
    // TODO(b/161399032): It would be nice to remove duplicate based on inheritance, i.e.,
    //  if there is ConcurrentMap<K,V> and Map<K,V>, Map<K,V> can be removed.
    return new ArrayList<>(new HashSet<>(extraInterfaces));
  }

  void processSuperType(
      DexType superType, List<DexType> extraInterfaces, LinkedList<DexClass> workList) {
    if (emulatedInterfaces.containsKey(superType)) {
      extraInterfaces.add(emulatedInterfaces.get(superType));
    } else {
      DexClass superClass = appView.definitionFor(superType);
      if (shouldProcessSuperclass(superClass)) {
        workList.add(superClass);
      }
    }
  }

  private boolean shouldProcessSuperclass(DexClass superclazz) {
    if (appView.options().isDesugaredLibraryCompilation()) {
      return false;
    }
    // TODO(b/161399032): Pay-as-you-go design: stop duplication on library boundaries.
    return superclazz != null && superclazz.isLibraryClass();
  }
}
