// 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.features;

import com.android.tools.r8.FeatureSplit;
import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ProgramResourceProvider;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.Sets;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;

public class ClassToFeatureSplitMap {

  private final Map<DexType, FeatureSplit> classToFeatureSplitMap = new IdentityHashMap<>();

  private ClassToFeatureSplitMap() {}

  public static ClassToFeatureSplitMap createEmptyClassToFeatureSplitMap() {
    return new ClassToFeatureSplitMap();
  }

  public static ClassToFeatureSplitMap createInitialClassToFeatureSplitMap(
      AppView<? extends AppInfoWithClassHierarchy> appView) {
    return createInitialClassToFeatureSplitMap(appView.options());
  }

  public static ClassToFeatureSplitMap createInitialClassToFeatureSplitMap(
      InternalOptions options) {
    DexItemFactory dexItemFactory = options.dexItemFactory();
    FeatureSplitConfiguration featureSplitConfiguration = options.featureSplitConfiguration;

    ClassToFeatureSplitMap result = new ClassToFeatureSplitMap();
    if (featureSplitConfiguration == null) {
      return result;
    }

    for (FeatureSplit featureSplit : featureSplitConfiguration.getFeatureSplits()) {
      for (ProgramResourceProvider programResourceProvider :
          featureSplit.getProgramResourceProviders()) {
        try {
          for (ProgramResource programResource : programResourceProvider.getProgramResources()) {
            for (String classDescriptor : programResource.getClassDescriptors()) {
              DexType type = dexItemFactory.createType(classDescriptor);
              result.classToFeatureSplitMap.put(type, featureSplit);
            }
          }
        } catch (ResourceException e) {
          throw options.reporter.fatalError(e.getMessage());
        }
      }
    }
    return result;
  }

  public Map<FeatureSplit, Set<DexProgramClass>> getFeatureSplitClasses(
      Set<DexProgramClass> classes) {
    Map<FeatureSplit, Set<DexProgramClass>> result = new IdentityHashMap<>();
    for (DexProgramClass clazz : classes) {
      FeatureSplit featureSplit = getFeatureSplit(clazz);
      if (featureSplit != null && !featureSplit.isBase()) {
        result.computeIfAbsent(featureSplit, ignore -> Sets.newIdentityHashSet()).add(clazz);
      }
    }
    return result;
  }

  public FeatureSplit getFeatureSplit(DexProgramClass clazz) {
    return getFeatureSplit(clazz.getType());
  }

  public FeatureSplit getFeatureSplit(DexType type) {
    return classToFeatureSplitMap.getOrDefault(type, FeatureSplit.BASE);
  }

  public boolean isEmpty() {
    return classToFeatureSplitMap.isEmpty();
  }

  public boolean isInBase(DexProgramClass clazz) {
    return getFeatureSplit(clazz).isBase();
  }

  public boolean isInBaseOrSameFeatureAs(DexProgramClass clazz, DexProgramClass context) {
    FeatureSplit split = getFeatureSplit(clazz);
    return split.isBase() || split == getFeatureSplit(context);
  }

  public boolean isInFeature(DexProgramClass clazz) {
    return !isInBase(clazz);
  }

  public boolean isInSameFeatureOrBothInBase(ProgramMethod a, ProgramMethod b) {
    return isInSameFeatureOrBothInBase(a.getHolder(), b.getHolder());
  }

  public boolean isInSameFeatureOrBothInBase(DexProgramClass a, DexProgramClass b) {
    return getFeatureSplit(a) == getFeatureSplit(b);
  }

  public ClassToFeatureSplitMap rewrittenWithLens(GraphLens lens) {
    ClassToFeatureSplitMap rewrittenClassToFeatureSplitMap = new ClassToFeatureSplitMap();
    classToFeatureSplitMap.forEach(
        (type, featureSplit) -> {
          DexType rewrittenType = lens.lookupType(type);
          if (rewrittenType.isIntType()) {
            // The type was removed by enum unboxing.
            return;
          }
          FeatureSplit existing =
              rewrittenClassToFeatureSplitMap.classToFeatureSplitMap.put(
                  rewrittenType, featureSplit);
          // If we map two classes to the same class then they must be from the same feature split.
          assert existing == null || existing == featureSplit;
        });
    return rewrittenClassToFeatureSplitMap;
  }

  public ClassToFeatureSplitMap withoutPrunedClasses(Set<DexType> prunedClasses) {
    ClassToFeatureSplitMap classToFeatureSplitMapAfterPruning = new ClassToFeatureSplitMap();
    classToFeatureSplitMap.forEach(
        (type, featureSplit) -> {
          if (!prunedClasses.contains(type)) {
            classToFeatureSplitMapAfterPruning.classToFeatureSplitMap.put(type, featureSplit);
          }
        });
    return classToFeatureSplitMapAfterPruning;
  }
}
