// 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.ProgramMethod;
import com.android.tools.r8.graph.PrunedItems;
import com.android.tools.r8.graph.lens.GraphLens;
import com.android.tools.r8.utils.CollectionUtils;
import com.android.tools.r8.utils.ForEachable;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public abstract class ProgramMethodSet extends DexClassAndMethodSetBase<ProgramMethod> {

  private static final ProgramMethodSet EMPTY = new EmptyProgramMethodSet();

  ProgramMethodSet() {
    super();
  }

  ProgramMethodSet(Map<DexMethod, ProgramMethod> backing) {
    super(backing);
  }

  ProgramMethodSet(int capacity) {
    super(capacity);
  }

  public static ProgramMethodSet create() {
    return new IdentityProgramMethodSet();
  }

  public static ProgramMethodSet create(int capacity) {
    return new IdentityProgramMethodSet(capacity);
  }

  public static ProgramMethodSet create(ProgramMethod element) {
    ProgramMethodSet result = create(1);
    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(Collection<ProgramMethod> methodSet) {
    ProgramMethodSet newMethodSet = create(methodSet.size());
    newMethodSet.addAll(methodSet);
    return newMethodSet;
  }

  public static ProgramMethodSet createConcurrent() {
    return new ConcurrentProgramMethodSet();
  }

  public static LinkedProgramMethodSet createLinked() {
    return new LinkedProgramMethodSet();
  }

  public static LinkedProgramMethodSet createLinked(int capacity) {
    return new LinkedProgramMethodSet(capacity);
  }

  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));
  }

  @SuppressWarnings("ReferenceEquality")
  public ProgramMethodSet rewrittenWithLens(DexDefinitionSupplier definitions, GraphLens lens) {
    GraphLens appliedLens = GraphLens.getIdentityLens();
    List<ProgramMethod> elementsToRemove = null;
    ProgramMethodSet rewrittenMethods = null;
    for (ProgramMethod method : this) {
      ProgramMethod rewrittenMethod = method.rewrittenWithLens(lens, appliedLens, definitions);
      if (rewrittenMethod == null) {
        assert lens.isEnumUnboxerLens();
        // If everything has been unchanged up until now, then record that we should remove this
        // method.
        if (rewrittenMethods == null) {
          if (elementsToRemove == null) {
            elementsToRemove = new ArrayList<>();
          }
          elementsToRemove.add(method);
        }
        continue;
      }
      if (rewrittenMethod == method) {
        if (rewrittenMethods != null) {
          rewrittenMethods.add(rewrittenMethod);
        }
      } else {
        if (rewrittenMethods == null) {
          rewrittenMethods = ProgramMethodSet.create(size());
          CollectionUtils.<ProgramMethod>forEachUntilExclusive(
              this, rewrittenMethods::add, method::isStructurallyEqualTo);
          if (elementsToRemove != null) {
            rewrittenMethods.removeAll(elementsToRemove);
            elementsToRemove = null;
          }
        }
        rewrittenMethods.add(rewrittenMethod);
      }
    }
    if (rewrittenMethods != null) {
      rewrittenMethods.trimCapacityIfSizeLessThan(size());
      return rewrittenMethods;
    } else {
      if (elementsToRemove != null) {
        removeAll(elementsToRemove);
      }
      return this;
    }
  }

  public ProgramMethodSet withoutPrunedItems(PrunedItems prunedItems) {
    removeIf(method -> prunedItems.isRemoved(method.getReference()));
    return this;
  }

  private static class ConcurrentProgramMethodSet extends ProgramMethodSet {

    @Override
    Map<DexMethod, ProgramMethod> createBacking() {
      return new ConcurrentHashMap<>();
    }

    @Override
    Map<DexMethod, ProgramMethod> createBacking(int capacity) {
      return new ConcurrentHashMap<>(capacity);
    }
  }

  private static class EmptyProgramMethodSet extends ProgramMethodSet {

    @Override
    Map<DexMethod, ProgramMethod> createBacking() {
      return ImmutableMap.of();
    }

    @Override
    Map<DexMethod, ProgramMethod> createBacking(int capacity) {
      return ImmutableMap.of();
    }
  }

  private static class IdentityProgramMethodSet extends ProgramMethodSet {

    IdentityProgramMethodSet() {
      super();
    }

    IdentityProgramMethodSet(int capacity) {
      super(capacity);
    }

    @Override
    Map<DexMethod, ProgramMethod> createBacking() {
      return new IdentityHashMap<>();
    }

    @Override
    Map<DexMethod, ProgramMethod> createBacking(int capacity) {
      return new IdentityHashMap<>(capacity);
    }
  }
}
