// Copyright (c) 2021, 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.utils.collections;

import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
import static com.android.tools.r8.utils.MapUtils.ignoreKey;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.IntFunction;

public class LongLivedProgramMethodMapBuilder<V>
    extends LongLivedCollectionBuilder<Map<DexMethod, V>, ProgramMethodMap<?>> {

  private LongLivedProgramMethodMapBuilder(
      GraphLens currentGraphLens,
      IntFunction<ProgramMethodMap<?>> factory,
      IntFunction<Map<DexMethod, V>> factoryForBuilder) {
    super(currentGraphLens, factory, factoryForBuilder);
  }

  public static <V> LongLivedProgramMethodMapBuilder<V> create(GraphLens currentGraphLens) {
    return new LongLivedProgramMethodMapBuilder<>(
        currentGraphLens, ProgramMethodMap::create, IdentityHashMap::new);
  }

  public static <V> LongLivedProgramMethodMapBuilder<V> createConcurrentBuilderForNonConcurrentMap(
      GraphLens currentGraphLens) {
    return new LongLivedProgramMethodMapBuilder<>(
        currentGraphLens, ProgramMethodMap::create, ConcurrentHashMap::new);
  }

  public V computeIfAbsent(
      ProgramMethod key, Function<ProgramMethod, V> fn, GraphLens currentGraphLens) {
    assert verifyIsRewrittenWithLens(currentGraphLens);
    return backing.computeIfAbsent(key.getReference(), ignoreKey(() -> fn.apply(key)));
  }

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

  public void put(ProgramMethod key, V value, GraphLens currentGraphLens) {
    // All methods in a long lived program method set should be rewritten up until the same graph
    // lens.
    assert verifyIsRewrittenWithLens(currentGraphLens);
    backing.put(key.getReference(), value);
  }

  public LongLivedProgramMethodMapBuilder<V> rewrittenWithLens(
      AppView<AppInfoWithLiveness> appView, BiFunction<V, GraphLens, V> valueRewriter) {
    return rewrittenWithLens(valueRewriter, appView.graphLens());
  }

  public LongLivedProgramMethodMapBuilder<V> rewrittenWithLens(
      BiFunction<V, GraphLens, V> valueRewriter, GraphLens newGraphLens) {
    // Check if the graph lens has changed (otherwise lens rewriting is not needed).
    if (newGraphLens == appliedGraphLens) {
      return this;
    }

    // Rewrite the backing.
    Map<DexMethod, V> rewrittenBacking = factoryForBuilder.apply(backing.size());
    backing.forEach(
        (key, value) -> {
          DexMethod rewrittenKey = newGraphLens.getRenamedMethodSignature(key, appliedGraphLens);
          V rewrittenValue = valueRewriter.apply(value, appliedGraphLens);
          assert !rewrittenBacking.containsKey(rewrittenKey);
          rewrittenBacking.put(rewrittenKey, rewrittenValue);
        });
    backing = rewrittenBacking;

    // Record that this collection is now rewritten up until the given graph lens.
    appliedGraphLens = newGraphLens;
    return this;
  }

  @SuppressWarnings("unchecked")
  public <U> ProgramMethodMap<U> build(
      AppView<AppInfoWithLiveness> appView, Function<V, U> valueTransformer) {
    assert verifyIsRewrittenWithLens(appView.graphLens());

    ProgramMethodMap<U> result = (ProgramMethodMap<U>) factory.apply(backing.size());
    backing.forEach(
        (key, value) -> {
          DexProgramClass holder = asProgramClassOrNull(appView.definitionFor(key.getHolderType()));
          ProgramMethod method = key.lookupOnProgramClass(holder);
          if (method != null) {
            result.put(method, valueTransformer.apply(value));
          } else {
            assert false;
          }
        });
    return result;
  }
}
