// Copyright (c) 2021, 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.optimize.enums.eligibility;

import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.google.common.collect.ImmutableList;

public abstract class Reason {
  public static final Reason ELIGIBLE = new StringReason("ELIGIBLE");
  public static final Reason ACCESSIBILITY = new StringReason("ACCESSIBILITY");
  public static final Reason ANNOTATION = new StringReason("ANNOTATION");
  public static final Reason PINNED = new StringReason("PINNED");
  public static final Reason DOWN_CAST = new StringReason("DOWN_CAST");
  public static final Reason SUBTYPES = new StringReason("SUBTYPES");
  public static final Reason MANY_INSTANCE_FIELDS = new StringReason("MANY_INSTANCE_FIELDS");
  public static final Reason DEFAULT_METHOD_INVOKE = new StringReason("DEFAULT_METHOD_INVOKE");
  public static final Reason UNRESOLVABLE_FIELD = new StringReason("UNRESOLVABLE_FIELD");
  public static final Reason CONST_CLASS = new StringReason("CONST_CLASS");
  public static final Reason INVALID_PHI = new StringReason("INVALID_PHI");
  public static final Reason NO_INIT = new StringReason("NO_INIT");
  public static final Reason INVALID_INIT = new StringReason("INVALID_INIT");
  public static final Reason INVALID_CLINIT = new StringReason("INVALID_CLINIT");
  public static final Reason INVALID_INVOKE = new StringReason("INVALID_INVOKE");
  public static final Reason INVALID_INVOKE_CUSTOM = new StringReason("INVALID_INVOKE_CUSTOM");
  public static final Reason INVALID_INVOKE_CLASSPATH =
      new StringReason("INVALID_INVOKE_CLASSPATH");
  public static final Reason INVALID_INVOKE_ON_ARRAY = new StringReason("INVALID_INVOKE_ON_ARRAY");
  public static final Reason IMPLICIT_UP_CAST_IN_RETURN =
      new StringReason("IMPLICIT_UP_CAST_IN_RETURN");
  public static final Reason INVALID_FIELD_PUT = new StringReason("INVALID_FIELD_PUT");
  public static final Reason INVALID_ARRAY_PUT = new StringReason("INVALID_ARRAY_PUT");
  public static final Reason TYPE_MISMATCH_FIELD_PUT = new StringReason("TYPE_MISMATCH_FIELD_PUT");
  public static final Reason INVALID_IF_TYPES = new StringReason("INVALID_IF_TYPES");
  public static final Reason ENUM_METHOD_CALLED_WITH_NULL_RECEIVER =
      new StringReason("ENUM_METHOD_CALLED_WITH_NULL_RECEIVER");
  public static final Reason OTHER_UNSUPPORTED_INSTRUCTION =
      new StringReason("OTHER_UNSUPPORTED_INSTRUCTION");

  public abstract Object getKind();

  @Override
  public abstract String toString();

  public static class StringReason extends Reason {

    private final String message;

    public StringReason(String message) {
      this.message = message;
    }

    @Override
    public Object getKind() {
      return this;
    }

    @Override
    public String toString() {
      return message;
    }
  }

  public static class IllegalInvokeWithImpreciseParameterTypeReason extends Reason {

    private final DexMethod invokedMethod;

    public IllegalInvokeWithImpreciseParameterTypeReason(DexMethod invokedMethod) {
      this.invokedMethod = invokedMethod;
    }

    @Override
    public Object getKind() {
      return getClass();
    }

    @Override
    public String toString() {
      return "IllegalInvokeWithImpreciseParameterType(" + invokedMethod.toSourceString() + ")";
    }
  }

  public static class MissingEnumStaticFieldValuesReason extends Reason {

    @Override
    public Object getKind() {
      return getClass();
    }

    @Override
    public String toString() {
      return "MissingEnumStaticFieldValues";
    }
  }

  public static class MissingContentsForEnumValuesArrayReason extends Reason {

    private final DexField valuesField;

    public MissingContentsForEnumValuesArrayReason(DexField valuesField) {
      this.valuesField = valuesField;
    }

    @Override
    public Object getKind() {
      return getClass();
    }

    @Override
    public String toString() {
      return "MissingContentsForEnumValuesArray(" + valuesField.toSourceString() + ")";
    }
  }

  public static class MissingInstanceFieldValueForEnumInstanceReason extends Reason {

    private final DexField enumField;
    private final int ordinal;
    private final DexField instanceField;

    public MissingInstanceFieldValueForEnumInstanceReason(
        DexField enumField, DexField instanceField) {
      this.enumField = enumField;
      this.ordinal = -1;
      this.instanceField = instanceField;
    }

    public MissingInstanceFieldValueForEnumInstanceReason(int ordinal, DexField instanceField) {
      this.enumField = null;
      this.ordinal = ordinal;
      this.instanceField = instanceField;
    }

    @Override
    public Object getKind() {
      return getClass();
    }

    @Override
    public String toString() {
      if (enumField != null) {
        return "MissingInstanceFieldValueForEnumInstance(enum field="
            + enumField.toSourceString()
            + ", instance field="
            + instanceField.toSourceString()
            + ")";
      }
      assert ordinal >= 0;
      return "MissingInstanceFieldValueForEnumInstance(ordinal="
          + ordinal
          + ", instance field="
          + instanceField.toSourceString()
          + ")";
    }
  }

  public static class MissingObjectStateForEnumInstanceReason extends Reason {

    private final DexField enumField;

    public MissingObjectStateForEnumInstanceReason(DexField enumField) {
      this.enumField = enumField;
    }

    @Override
    public Object getKind() {
      return getClass();
    }

    @Override
    public String toString() {
      return "MissingObjectStateForEnumInstance(" + enumField + ")";
    }
  }

  public static class UnsupportedInstanceFieldValueForEnumInstanceReason extends Reason {

    private final int ordinal;
    private final DexField instanceField;

    public UnsupportedInstanceFieldValueForEnumInstanceReason(int ordinal, DexField instanceField) {
      this.ordinal = ordinal;
      this.instanceField = instanceField;
    }

    @Override
    public Object getKind() {
      return getClass();
    }

    @Override
    public String toString() {
      return "UnsupportedInstanceFieldValueForEnumInstance(ordinal="
          + ordinal
          + ", instance field="
          + instanceField.toSourceString()
          + ")";
    }
  }

  public static class UnsupportedLibraryInvokeReason extends Reason {

    private final DexMethod invokedMethod;

    public UnsupportedLibraryInvokeReason(DexMethod invokedMethod) {
      this.invokedMethod = invokedMethod;
    }

    @Override
    public Object getKind() {
      return ImmutableList.of(getClass(), invokedMethod);
    }

    @Override
    public String toString() {
      return "UnsupportedLibraryInvoke(" + invokedMethod.toSourceString() + ")";
    }
  }

  public static class UnsupportedStaticFieldReason extends Reason {

    private final DexField field;

    public UnsupportedStaticFieldReason(DexField field) {
      this.field = field;
    }

    @Override
    public Object getKind() {
      return getClass();
    }

    @Override
    public String toString() {
      return "UnsupportedStaticField(" + field.toSourceString() + ")";
    }
  }
}
