// 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.structural;

import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.utils.structural.StructuralItem.CompareToAccept;
import com.android.tools.r8.utils.structural.StructuralItem.HashingAccept;
import java.util.Comparator;
import java.util.Iterator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;

/** Base class to share most visiting methods */
public abstract class CompareToVisitorBase extends CompareToVisitor {

  @Override
  public final int visitBool(boolean value1, boolean value2) {
    return Boolean.compare(value1, value2);
  }

  @Override
  public final int visitInt(int value1, int value2) {
    return Integer.compare(value1, value2);
  }

  @Override
  public int visitLong(long value1, long value2) {
    return Long.compare(value1, value2);
  }

  @Override
  public int visitFloat(float value1, float value2) {
    return Float.compare(value1, value2);
  }

  @Override
  public int visitDouble(double value1, double value2) {
    return Double.compare(value1, value2);
  }

  @Override
  public <S> int visitItemIterator(
      Iterator<S> it1, Iterator<S> it2, CompareToAccept<S> compareToAccept) {
    int order = 0;
    while (order == 0 && it1.hasNext() && it2.hasNext()) {
      order = compareToAccept.acceptCompareTo(it1.next(), it2.next(), this);
    }
    if (order == 0) {
      order = visitBool(it1.hasNext(), it2.hasNext());
    }
    return order;
  }

  @Override
  public int visitDexString(DexString string1, DexString string2) {
    return string1.compareTo(string2);
  }

  @Override
  public int visitDexReference(DexReference reference1, DexReference reference2) {
    int order = visitInt(reference1.referenceTypeOrder(), reference2.referenceTypeOrder());
    if (order == 0) {
      assert reference1.getClass() == reference2.getClass();
      if (reference1.isDexType()) {
        order = visitDexType(reference1.asDexType(), reference2.asDexType());
      } else if (reference1.isDexField()) {
        order = visitDexField(reference1.asDexField(), reference2.asDexField());
      } else {
        order = visitDexMethod(reference1.asDexMethod(), reference2.asDexMethod());
      }
    }
    return order;
  }

  @Override
  public final <S> int visit(S item1, S item2, Comparator<S> comparator) {
    return comparator.compare(item1, item2);
  }

  @Override
  public final <S> int visit(S item1, S item2, StructuralMapping<S> accept) {
    ItemSpecification<S> itemVisitor = new ItemSpecification<>(item1, item2, this);
    accept.apply(itemVisitor);
    return itemVisitor.order;
  }

  private static class ItemSpecification<T>
      extends StructuralSpecification<T, ItemSpecification<T>> {

    private final CompareToVisitorBase parent;
    private final T item1;
    private final T item2;
    private int order = 0;

    private ItemSpecification(T item1, T item2, CompareToVisitorBase parent) {
      this.item1 = item1;
      this.item2 = item2;
      this.parent = parent;
    }

    @Override
    ItemSpecification<T> self() {
      return this;
    }

    @Override
    public ItemSpecification<T> withAssert(Predicate<T> predicate) {
      assert predicate.test(item1);
      assert predicate.test(item2);
      return this;
    }

    @Override
    public ItemSpecification<T> withBool(Predicate<T> getter) {
      if (order == 0) {
        order = parent.visitBool(getter.test(item1), getter.test(item2));
      }
      return this;
    }

    @Override
    public ItemSpecification<T> withInt(ToIntFunction<T> getter) {
      if (order == 0) {
        order = parent.visitInt(getter.applyAsInt(item1), getter.applyAsInt(item2));
      }
      return this;
    }

    @Override
    public ItemSpecification<T> withLong(ToLongFunction<T> getter) {
      if (order == 0) {
        order = parent.visitLong(getter.applyAsLong(item1), getter.applyAsLong(item2));
      }
      return this;
    }

    @Override
    public ItemSpecification<T> withDouble(ToDoubleFunction<T> getter) {
      if (order == 0) {
        order = parent.visitDouble(getter.applyAsDouble(item1), getter.applyAsDouble(item2));
      }
      return this;
    }

    @Override
    public ItemSpecification<T> withIntArray(Function<T, int[]> getter) {
      if (order == 0) {
        int[] is1 = getter.apply(item1);
        int[] is2 = getter.apply(item2);
        int minLength = Math.min(is1.length, is2.length);
        for (int i = 0; i < minLength && order == 0; i++) {
          order = parent.visitInt(is1[i], is2[i]);
        }
        if (order == 0) {
          order = parent.visitInt(is1.length, is2.length);
        }
      }
      return this;
    }

    @Override
    public ItemSpecification<T> withShortArray(Function<T, short[]> getter) {
      if (order == 0) {
        short[] is1 = getter.apply(item1);
        short[] is2 = getter.apply(item2);
        int minLength = Math.min(is1.length, is2.length);
        for (int i = 0; i < minLength && order == 0; i++) {
          order = parent.visitInt(is1[i], is2[i]);
        }
        if (order == 0) {
          order = parent.visitInt(is1.length, is2.length);
        }
      }
      return this;
    }

    @Override
    public <S> ItemSpecification<T> withConditionalCustomItem(
        Predicate<T> predicate,
        Function<T, S> getter,
        CompareToAccept<S> compare,
        HashingAccept<S> hasher) {
      if (order == 0) {
        boolean test1 = predicate.test(item1);
        boolean test2 = predicate.test(item2);
        if (test1 && test2) {
          order = compare.acceptCompareTo(getter.apply(item1), getter.apply(item2), parent);
        } else {
          order = parent.visitBool(test1, test2);
        }
      }
      return this;
    }

    @Override
    protected <S> ItemSpecification<T> withItemIterator(
        Function<T, Iterator<S>> getter, CompareToAccept<S> compare, HashingAccept<S> hasher) {
      if (order == 0) {
        order = parent.visitItemIterator(getter.apply(item1), getter.apply(item2), compare);
      }
      return this;
    }

    @Override
    public ItemSpecification<T> withDexReference(Function<T, DexReference> getter) {
      if (order == 0) {
        order = parent.visitDexReference(getter.apply(item1), getter.apply(item2));
      }
      return this;
    }
  }
}
