// 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.android.tools.r8.ir.code.CatchHandlers.CatchHandler;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;

public class CatchHandlers<T> implements Iterable<CatchHandler<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;
    }

    public T getTarget() {
      return target;
    }

    public DexType getGuard() {
      return guard;
    }
  }

  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 DexType getGuard(int index) {
    return guards.get(index);
  }

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

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

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

  public CatchHandlers<T> appendGuard(DexType guard, T target) {
    assert !guards.contains(guard);
    List<DexType> newGuards = ImmutableList.<DexType>builder().addAll(guards).add(guard).build();
    List<T> newTargets = ImmutableList.<T>builder().addAll(targets).add(target).build();
    return new CatchHandlers<>(newGuards, newTargets);
  }

  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 Iterator<CatchHandler<T>> iterator() {
    return new Iterator<CatchHandler<T>>() {

      private int nextIndex = 0;

      @Override
      public boolean hasNext() {
        return nextIndex < size();
      }

      @Override
      public CatchHandler<T> next() {
        DexType guard = guards.get(nextIndex);
        T target = targets.get(nextIndex);
        ++nextIndex;
        return new CatchHandler<>(guard, target);
      }
    };
  }

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