// 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.utils.collections;

import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedMethod;
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.utils.ForEachable;
import com.google.common.collect.ImmutableMap;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

public class ProgramMethodSet extends DexClassAndMethodSetBase<ProgramMethod> {

  private static final ProgramMethodSet EMPTY = new ProgramMethodSet(ImmutableMap::of);

  protected ProgramMethodSet(Supplier<? extends Map<DexMethod, ProgramMethod>> backingFactory) {
    super(backingFactory);
  }

  protected ProgramMethodSet(
      Supplier<? extends Map<DexMethod, ProgramMethod>> backingFactory,
      Map<DexMethod, ProgramMethod> backing) {
    super(backingFactory, backing);
  }

  public static ProgramMethodSet create() {
    return new ProgramMethodSet(IdentityHashMap::new);
  }

  public static ProgramMethodSet create(int capacity) {
    return new ProgramMethodSet(IdentityHashMap::new, new IdentityHashMap<>(capacity));
  }

  public static ProgramMethodSet create(ProgramMethod element) {
    ProgramMethodSet result = create();
    result.add(element);
    return result;
  }

  public static ProgramMethodSet create(ForEachable<ProgramMethod> methods) {
    ProgramMethodSet result = create();
    methods.forEach(result::add);
    return result;
  }

  public static ProgramMethodSet create(ProgramMethodSet methodSet) {
    ProgramMethodSet newMethodSet = create();
    newMethodSet.addAll(methodSet);
    return newMethodSet;
  }

  public static ProgramMethodSet createConcurrent() {
    return new ProgramMethodSet(ConcurrentHashMap::new);
  }

  public static ProgramMethodSet createLinked() {
    return new ProgramMethodSet(LinkedHashMap::new);
  }

  public static ProgramMethodSet empty() {
    return EMPTY;
  }

  public void addAll(ProgramMethodSet methods) {
    backing.putAll(methods.backing);
  }

  public boolean createAndAdd(DexProgramClass clazz, DexEncodedMethod definition) {
    return add(new ProgramMethod(clazz, definition));
  }

  public ProgramMethodSet rewrittenWithLens(DexDefinitionSupplier definitions, GraphLens lens) {
    ProgramMethodSet rewritten = new ProgramMethodSet(backingFactory);
    forEach(
        method -> {
          ProgramMethod newMethod = lens.mapProgramMethod(method, definitions);
          if (newMethod != null) {
            rewritten.add(newMethod);
          }
        });
    return rewritten;
  }
}
