// Copyright (c) 2017, 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.AppView;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.utils.Int2StructuralItemArrayMap;
import com.android.tools.r8.utils.structural.Equatable;
import com.android.tools.r8.utils.structural.HashCodeVisitor;
import com.android.tools.r8.utils.structural.StructuralItem;
import com.android.tools.r8.utils.structural.StructuralMapping;
import com.android.tools.r8.utils.structural.StructuralSpecification;
import java.util.function.Predicate;

public abstract class Position implements StructuralItem<Position> {

  // Compare ID(s) for positions.
  private static final int SOURCE_POSITION_COMPARE_ID = 1;
  private static final int SYNTHETIC_POSITION_COMPARE_ID = 2;
  private static final int OUTLINE_POSITION_COMPARE_ID = 3;
  private static final int OUTLINE_CALLER_POSITION_COMPARE_ID = 4;

  protected final int line;
  protected final DexMethod method;

  // If there's no inlining, callerPosition is null.
  //
  // For an inlined instruction its Position contains the inlinee's line and method and
  // callerPosition is the position of the invoke instruction in the caller.
  protected final Position callerPosition;

  private final boolean removeInnerFramesIfThrowingNpe;
  private final boolean isD8R8Synthesized;

  private Position(
      int line,
      DexMethod method,
      Position callerPosition,
      boolean removeInnerFramesIfThrowingNpe,
      boolean isD8R8Synthesized) {
    this.line = line;
    this.method = method;
    this.callerPosition = callerPosition;
    this.removeInnerFramesIfThrowingNpe = removeInnerFramesIfThrowingNpe;
    this.isD8R8Synthesized = isD8R8Synthesized;
  }

  public boolean isSyntheticPosition() {
    return false;
  }

  public boolean isRemoveInnerFramesIfThrowingNpe() {
    return removeInnerFramesIfThrowingNpe;
  }

  public boolean isD8R8Synthesized() {
    return isD8R8Synthesized;
  }

  public boolean isOutline() {
    return false;
  }

  public boolean isOutlineCaller() {
    return false;
  }

  public DexMethod getOutlineCallee() {
    return null;
  }

  public Int2StructuralItemArrayMap<Position> getOutlinePositions() {
    return null;
  }

  public boolean hasCallerPosition() {
    return callerPosition != null;
  }

  public Position getCallerPosition() {
    return callerPosition;
  }

  public int getLine() {
    return line;
  }

  public DexMethod getMethod() {
    return method;
  }

  public static Position none() {
    return SourcePosition.NO_POSITION;
  }

  public boolean hasFile() {
    return false;
  }

  public DexString getFile() {
    return null;
  }

  @Override
  public Position self() {
    return this;
  }

  // Unique id to determine the ordering of positions
  public abstract int getCompareToId();

  @Override
  public abstract StructuralMapping<Position> getStructuralMapping();

  private static void specifyBasePosition(StructuralSpecification<Position, ?> spec) {
    spec.withInt(Position::getCompareToId)
        .withInt(Position::getLine)
        .withNullableItem(Position::getMethod)
        .withNullableItem(Position::getCallerPosition)
        .withBool(Position::isRemoveInnerFramesIfThrowingNpe)
        .withBool(Position::isD8R8Synthesized);
  }

  public static Position syntheticNone() {
    return SyntheticPosition.NO_POSITION_SYNTHETIC;
  }

  public static Position getPositionForInlining(
      AppView<?> appView, InvokeMethod invoke, ProgramMethod context) {
    Position position = invoke.getPosition();
    if (position.method == null) {
      assert position.isNone();
      position = SourcePosition.builder().setMethod(context.getReference()).build();
    }
    if (context.getDefinition().isD8R8Synthesized()) {
      // Some rewritings map a synthetic method back to an original in the program. To ensure we
      // have correct line information we have to rewrite the positions as inline position
      // therefore we only check if the original method is present.
      DexMethod originalMethodSignature =
          appView.graphLens().getOriginalMethodSignature(context.getReference());
      assert position.hasMethodInChain(originalMethodSignature);
    } else {
      assert position.getOutermostCaller().method
          == appView.graphLens().getOriginalMethodSignature(context.getReference());
    }
    return position;
  }

  public boolean isNone() {
    return line == -1;
  }

  public boolean isSyntheticNone() {
    return this == syntheticNone();
  }

  public boolean isSome() {
    return !isNone();
  }

  // Follow the linked list of callerPositions and return the last.
  // Return this if no inliner.
  public Position getOutermostCaller() {
    Position lastPosition = this;
    while (lastPosition.callerPosition != null) {
      lastPosition = lastPosition.callerPosition;
    }
    return lastPosition;
  }

  public Position getOutermostCallerMatchingOrElse(
      Predicate<Position> predicate, Position defaultValue) {
    Position outerMostMatching = getOutermostCallerMatching(predicate, false);
    return outerMostMatching == null ? defaultValue : outerMostMatching;
  }

  private Position getOutermostCallerMatching(
      Predicate<Position> predicate, boolean isCallerPosition) {
    if (hasCallerPosition()) {
      Position position = getCallerPosition().getOutermostCallerMatching(predicate, true);
      if (position != null) {
        return position;
      }
    }
    if (isCallerPosition && predicate.test(this)) {
      return this;
    }
    return null;
  }

  public boolean hasPositionMatching(Predicate<Position> positionPredicate) {
    Position lastPosition = this;
    while (lastPosition != null) {
      if (positionPredicate.test(lastPosition)) {
        return true;
      }
      lastPosition = lastPosition.getCallerPosition();
    }
    return false;
  }

  public boolean hasMethodInChain(DexMethod method) {
    return hasPositionMatching(position -> position.getMethod() == method);
  }

  public Position withOutermostCallerPosition(Position newOutermostCallerPosition) {
    return builderWithCopy()
        .setCallerPosition(
            hasCallerPosition()
                ? getCallerPosition().withOutermostCallerPosition(newOutermostCallerPosition)
                : newOutermostCallerPosition)
        .build();
  }

  public Position replacePosition(Position originalPosition, Position newPosition) {
    if (this == originalPosition) {
      return newPosition;
    }
    return hasCallerPosition()
        ? builderWithCopy()
            .setCallerPosition(callerPosition.replacePosition(originalPosition, newPosition))
            .build()
        : this;
  }

  @Override
  public final boolean equals(Object other) {
    return Equatable.equalsImpl(this, other);
  }

  @Override
  public final int hashCode() {
    return HashCodeVisitor.run(this);
  }

  @Override
  public String toString() {
    if (isNone()) {
      return "--";
    }
    StringBuilder builder = new StringBuilder();
    if (hasFile()) {
      builder.append(getFile()).append(":");
    }
    builder.append("#").append(line);
    if (method != null && callerPosition != null) {
      builder.append(":").append(method.name);
    }
    if (callerPosition != null) {
      Position caller = callerPosition;
      while (caller != null) {
        builder.append(";").append(caller.line).append(":").append(caller.method.name);
        caller = caller.callerPosition;
      }
    }
    if (isOutline()) {
      builder.append(", isOutline = true");
    }
    if (getOutlineCallee() != null) {
      builder.append(", outlineCallee = ").append(getOutlineCallee());
    }
    if (getOutlinePositions() != null) {
      builder.append(", outlineCallerPositions = ").append(getOutlinePositions());
    }
    return builder.toString();
  }

  public abstract PositionBuilder<?, ?> builderWithCopy();

  public abstract static class PositionBuilder<
      P extends Position, B extends PositionBuilder<P, B>> {

    protected int line = -1;
    protected DexMethod method;
    protected Position callerPosition;
    protected boolean removeInnerFramesIfThrowingNpe;
    protected boolean isD8R8Synthesized;

    protected boolean noCheckOfPosition;
    protected boolean noCheckOfMethod;

    abstract B self();

    public B setLine(int line) {
      this.line = line;
      return self();
    }

    public boolean hasLine() {
      return line > -1;
    }

    public B setMethod(DexMethod method) {
      this.method = method;
      return self();
    }

    public B setCallerPosition(Position callerPosition) {
      this.callerPosition = callerPosition;
      return self();
    }

    public B setRemoveInnerFramesIfThrowingNpe(boolean removeInnerFramesIfThrowingNpe) {
      this.removeInnerFramesIfThrowingNpe = removeInnerFramesIfThrowingNpe;
      return self();
    }

    public B setIsD8R8Synthesized(boolean isD8R8Synthesized) {
      this.isD8R8Synthesized = isD8R8Synthesized;
      return self();
    }

    public B disableLineCheck() {
      noCheckOfPosition = true;
      return self();
    }

    public B disableMethodCheck() {
      noCheckOfMethod = true;
      return self();
    }

    public abstract P build();
  }

  public static class SourcePosition extends Position {

    // A no-position marker. Not having a position means the position is implicitly defined by the
    // context, e.g., the marker does not materialize anything concrete.
    private static final SourcePosition NO_POSITION =
        new SourcePosition(-1, null, null, false, false, null);

    public final DexString file;

    private static void specify(StructuralSpecification<Position, ?> spec) {
      spec.withSpec(Position::specifyBasePosition).withNullableItem(Position::getFile);
    }

    private SourcePosition(
        int line,
        DexMethod method,
        Position callerPosition,
        boolean removeInnerFramesIfThrowingNpe,
        boolean isD8R8Synthesized,
        DexString file) {
      super(line, method, callerPosition, removeInnerFramesIfThrowingNpe, isD8R8Synthesized);
      this.file = file;
      assert callerPosition == null || callerPosition.method != null;
    }

    @Override
    public boolean hasFile() {
      return file != null;
    }

    @Override
    public DexString getFile() {
      return file;
    }

    @Override
    public int getCompareToId() {
      return SOURCE_POSITION_COMPARE_ID;
    }

    @Override
    public PositionBuilder<?, ?> builderWithCopy() {
      return builder()
          .setLine(line)
          .setFile(file)
          .setMethod(method)
          .setCallerPosition(callerPosition)
          .setRemoveInnerFramesIfThrowingNpe(isRemoveInnerFramesIfThrowingNpe())
          .setIsD8R8Synthesized(isD8R8Synthesized());
    }

    @Override
    public StructuralMapping<Position> getStructuralMapping() {
      return SourcePosition::specify;
    }

    public static SourcePositionBuilder builder() {
      return new SourcePositionBuilder();
    }

    public static class SourcePositionBuilder
        extends PositionBuilder<SourcePosition, SourcePositionBuilder> {

      private DexString file;

      @Override
      SourcePositionBuilder self() {
        return this;
      }

      public SourcePositionBuilder setFile(DexString file) {
        this.file = file;
        return this;
      }

      @Override
      public SourcePosition build() {
        assert noCheckOfPosition || line >= 0;
        assert noCheckOfMethod || method != null;
        return new SourcePosition(
            line, method, callerPosition, removeInnerFramesIfThrowingNpe, isD8R8Synthesized, file);
      }
    }
  }

  public static class SyntheticPosition extends Position {

    // A synthetic marker position that should never materialize.
    // This is used specifically to mark exceptional exit blocks from synchronized methods in
    // release.
    private static final Position NO_POSITION_SYNTHETIC =
        new SyntheticPosition(-1, null, null, false, false);

    private SyntheticPosition(
        int line,
        DexMethod method,
        Position callerPosition,
        boolean removeInnerFramesIfThrowingNpe,
        boolean isD8R8Synthesized) {
      super(line, method, callerPosition, removeInnerFramesIfThrowingNpe, isD8R8Synthesized);
    }

    @Override
    public boolean isSyntheticPosition() {
      return true;
    }

    @Override
    public int getCompareToId() {
      return SYNTHETIC_POSITION_COMPARE_ID;
    }

    @Override
    public PositionBuilder<?, ?> builderWithCopy() {
      return builder()
          .setLine(line)
          .setMethod(method)
          .setCallerPosition(callerPosition)
          .setRemoveInnerFramesIfThrowingNpe(isRemoveInnerFramesIfThrowingNpe())
          .setIsD8R8Synthesized(isD8R8Synthesized());
    }

    @Override
    public StructuralMapping<Position> getStructuralMapping() {
      return Position::specifyBasePosition;
    }

    public static SyntheticPositionBuilder builder() {
      return new SyntheticPositionBuilder();
    }

    public static class SyntheticPositionBuilder
        extends PositionBuilder<SyntheticPosition, SyntheticPositionBuilder> {

      private SyntheticPositionBuilder() {}

      @Override
      SyntheticPositionBuilder self() {
        return this;
      }

      @Override
      public SyntheticPosition build() {
        assert noCheckOfPosition || line >= 0;
        assert noCheckOfMethod || method != null;
        return new SyntheticPosition(
            line, method, callerPosition, removeInnerFramesIfThrowingNpe, isD8R8Synthesized);
      }
    }
  }

  public static class OutlinePosition extends Position {

    private OutlinePosition(
        int line,
        DexMethod method,
        Position callerPosition,
        boolean removeInnerFramesIfThrowingNpe,
        boolean isD8R8Synthesized) {
      super(line, method, callerPosition, removeInnerFramesIfThrowingNpe, isD8R8Synthesized);
    }

    @Override
    public boolean isOutline() {
      return true;
    }

    @Override
    public int getCompareToId() {
      return OUTLINE_POSITION_COMPARE_ID;
    }

    @Override
    public PositionBuilder<?, ?> builderWithCopy() {
      return builder()
          .setLine(line)
          .setMethod(method)
          .setCallerPosition(callerPosition)
          .setRemoveInnerFramesIfThrowingNpe(isRemoveInnerFramesIfThrowingNpe())
          .setIsD8R8Synthesized(isD8R8Synthesized());
    }

    @Override
    public StructuralMapping<Position> getStructuralMapping() {
      return Position::specifyBasePosition;
    }

    public static OutlinePositionBuilder builder() {
      return new OutlinePositionBuilder();
    }

    public static class OutlinePositionBuilder
        extends PositionBuilder<OutlinePosition, OutlinePositionBuilder> {

      private OutlinePositionBuilder() {}

      @Override
      OutlinePositionBuilder self() {
        return this;
      }

      @Override
      public OutlinePosition build() {
        return new OutlinePosition(
            line, method, callerPosition, removeInnerFramesIfThrowingNpe, isD8R8Synthesized);
      }
    }
  }

  public static class OutlineCallerPosition extends Position {

    private final Int2StructuralItemArrayMap<Position> outlinePositions;
    private final DexMethod outlineCallee;
    private final boolean isOutline;

    public static void specify(StructuralSpecification<Position, ?> spec) {
      spec.withSpec(Position::specifyBasePosition)
          .withBool(Position::isOutline)
          .withItem(Position::getOutlineCallee)
          .withItem(Position::getOutlinePositions);
    }

    private OutlineCallerPosition(
        int line,
        DexMethod method,
        Position callerPosition,
        boolean removeInnerFramesIfThrowingNpe,
        boolean isD8R8Synthesized,
        Int2StructuralItemArrayMap<Position> outlinePositions,
        DexMethod outlineCallee,
        boolean isOutline) {
      super(line, method, callerPosition, removeInnerFramesIfThrowingNpe, isD8R8Synthesized);
      this.outlinePositions = outlinePositions;
      this.outlineCallee = outlineCallee;
      this.isOutline = isOutline;
    }

    @Override
    public boolean isNone() {
      return false;
    }

    @Override
    public int getCompareToId() {
      return OUTLINE_CALLER_POSITION_COMPARE_ID;
    }

    @Override
    public PositionBuilder<?, ?> builderWithCopy() {
      OutlineCallerPositionBuilder outlineCallerPositionBuilder =
          builder()
              .setLine(line)
              .setMethod(method)
              .setCallerPosition(callerPosition)
              .setOutlineCallee(outlineCallee)
              .setIsOutline(isOutline)
              .setRemoveInnerFramesIfThrowingNpe(isRemoveInnerFramesIfThrowingNpe())
              .setIsD8R8Synthesized(isD8R8Synthesized());
      outlinePositions.forEach(outlineCallerPositionBuilder::addOutlinePosition);
      return outlineCallerPositionBuilder;
    }

    @Override
    public boolean isOutline() {
      return isOutline;
    }

    @Override
    public boolean isOutlineCaller() {
      return true;
    }

    @Override
    public DexMethod getOutlineCallee() {
      return outlineCallee;
    }

    @Override
    public Int2StructuralItemArrayMap<Position> getOutlinePositions() {
      return outlinePositions;
    }

    @Override
    public StructuralMapping<Position> getStructuralMapping() {
      return OutlineCallerPosition::specify;
    }

    public static OutlineCallerPositionBuilder builder() {
      return new OutlineCallerPositionBuilder();
    }

    public static class OutlineCallerPositionBuilder
        extends PositionBuilder<OutlineCallerPosition, OutlineCallerPositionBuilder> {

      private final Int2StructuralItemArrayMap.Builder<Position> outlinePositionsBuilder =
          Int2StructuralItemArrayMap.builder();
      private DexMethod outlineCallee;
      private boolean isOutline;

      private OutlineCallerPositionBuilder() {}

      @Override
      OutlineCallerPositionBuilder self() {
        return this;
      }

      public OutlineCallerPositionBuilder setOutlineCallee(DexMethod outlineCallee) {
        this.outlineCallee = outlineCallee;
        return this;
      }

      public OutlineCallerPositionBuilder addOutlinePosition(int line, Position callerPosition) {
        outlinePositionsBuilder.put(line, callerPosition);
        return this;
      }

      public OutlineCallerPositionBuilder setIsOutline(boolean isOutline) {
        this.isOutline = isOutline;
        return this;
      }

      public boolean hasOutlinePositions() {
        return !outlinePositionsBuilder.isEmpty();
      }

      @Override
      public OutlineCallerPosition build() {
        assert noCheckOfPosition || line >= 0;
        assert noCheckOfMethod || method != null;
        return new OutlineCallerPosition(
            line,
            method,
            callerPosition,
            removeInnerFramesIfThrowingNpe,
            isD8R8Synthesized,
            outlinePositionsBuilder.build(),
            outlineCallee,
            isOutline);
      }
    }
  }
}
