// Copyright (c) 2016, 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.code;

import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;

public class CatchHandlers<T> {

  public static class CatchHandler<T> {

    public final DexType guard;
    public final T target;

    public CatchHandler(DexType guard, T target) {
      this.guard = guard;
      this.target = target;
    }
  }

  private final List<DexType> guards;
  private final List<T> targets;
  private Set<T> uniqueTargets;

  public static final CatchHandlers<Integer> EMPTY_INDICES = new CatchHandlers<>();
  public static final CatchHandlers<BasicBlock> EMPTY_BASIC_BLOCK = new CatchHandlers<>();

  private CatchHandlers() {
    guards = ImmutableList.of();
    targets = ImmutableList.of();
  }

  public CatchHandlers(List<DexType> guards, List<T> targets) {
    assert !guards.isEmpty();
    assert guards.size() == targets.size();
    // Guava ImmutableList does not support null elements.
    this.guards = ImmutableList.copyOf(guards);
    this.targets = ImmutableList.copyOf(targets);
  }

  public boolean isEmpty() {
    return size() == 0;
  }

  public int size() {
    assert guards.size() == targets.size();
    return guards.size();
  }

  public List<DexType> getGuards() {
    return guards;
  }

  public List<T> getAllTargets() {
    return targets;
  }

  public Set<T> getUniqueTargets() {
    if (uniqueTargets == null) {
      uniqueTargets = ImmutableSet.copyOf(targets);
    }
    return uniqueTargets;
  }

  public boolean hasCatchAll() {
    return getGuards().size() > 0 &&
        getGuards().get(getGuards().size() - 1) == DexItemFactory.catchAllType;
  }

  public CatchHandlers<T> removeGuard(DexType guardToBeRemoved) {
    List<DexType> newGuards = new ArrayList<>();
    List<T> newTargets = new ArrayList<>();
    forEach(
        (guard, target) -> {
          if (guard != guardToBeRemoved) {
            newGuards.add(guard);
            newTargets.add(target);
          }
        });
    return new CatchHandlers<>(newGuards, newTargets);
  }

  public void forEach(BiConsumer<DexType, T> consumer) {
    for (int i = 0; i < size(); ++i) {
      consumer.accept(guards.get(i), targets.get(i));
    }
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof CatchHandlers)) {
      return false;
    }
    CatchHandlers<?> that = (CatchHandlers<?>) o;
    return guards.equals(that.guards) && targets.equals(that.targets);
  }

  @Override
  public int hashCode() {
    return 31 * guards.hashCode() + targets.hashCode();
  }
}
