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

import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.InvokeVirtual;
import com.android.tools.r8.ir.code.NewInstance;
import com.google.common.collect.Sets;
import java.util.Set;

/**
 * StringBuilderNode defines a single point where a string builder operation occur or some abstract
 * state changes. The node can be assembled into a graph by defining predecessors and successors.
 */
class StringBuilderNode {

  interface StringBuilderInstruction {

    Instruction getInstruction();

    boolean isStringBuilderInstructionNode();

    StringBuilderInstruction asStringBuilderInstructionNode();
  }

  interface InitOrAppend extends StringBuilderInstruction {

    boolean hasConstantArgument();

    String getConstantArgument();

    void setConstantArgument(String constantArgument);

    void setImplicitToStringNode(ImplicitToStringNode node);

    ImplicitToStringNode getImplicitToStringNode();
  }

  private final Set<StringBuilderNode> successors = Sets.newLinkedHashSet();
  private final Set<StringBuilderNode> predecessors = Sets.newLinkedHashSet();

  // Field uses to ensure that munching will not operate on the same value multiple times. If all
  // peep holes would look in the same direction, this field could be removed.
  private boolean isDead = false;

  private StringBuilderNode() {}

  boolean isEscapeNode() {
    return false;
  }

  boolean isMutateNode() {
    return false;
  }

  boolean isSplitReferenceNode() {
    return false;
  }

  boolean isLoopNode() {
    return false;
  }

  boolean isNewInstanceNode() {
    return false;
  }

  boolean isInitNode() {
    return false;
  }

  boolean isAppendNode() {
    return false;
  }

  boolean isInitOrAppend() {
    return false;
  }

  boolean isToStringNode() {
    return false;
  }

  boolean isInspectingNode() {
    return false;
  }

  boolean isOtherStringBuilderNode() {
    return false;
  }

  boolean isImplicitToStringNode() {
    return false;
  }

  boolean isStringBuilderInstructionNode() {
    return false;
  }

  NewInstanceNode asNewInstanceNode() {
    return null;
  }

  InitNode asInitNode() {
    return null;
  }

  AppendNode asAppendNode() {
    return null;
  }

  InitOrAppend asInitOrAppend() {
    return null;
  }

  ToStringNode asToStringNode() {
    return null;
  }

  InspectingNode asInspectingNode() {
    return null;
  }

  OtherStringBuilderNode asOtherStringBuilderNode() {
    return null;
  }

  ImplicitToStringNode asImplicitToStringNode() {
    return null;
  }

  StringBuilderInstruction asStringBuilderInstructionNode() {
    return null;
  }

  boolean isDead() {
    return isDead;
  }

  boolean hasSingleSuccessor() {
    return successors.size() == 1;
  }

  StringBuilderNode getSingleSuccessor() {
    assert hasSingleSuccessor();
    return successors.iterator().next();
  }

  void addSuccessor(StringBuilderNode successor) {
    successors.add(successor);
    successor.predecessors.add(this);
  }

  Set<StringBuilderNode> getSuccessors() {
    return successors;
  }

  boolean hasSinglePredecessor() {
    return predecessors.size() == 1;
  }

  StringBuilderNode getSinglePredecessor() {
    assert hasSinglePredecessor();
    return predecessors.iterator().next();
  }

  Set<StringBuilderNode> getPredecessors() {
    return predecessors;
  }

  void addPredecessor(StringBuilderNode predecessor) {
    predecessors.add(predecessor);
  }

  void removeNode() {
    for (StringBuilderNode successor : this.getSuccessors()) {
      successor.getPredecessors().remove(this);
      successor.getPredecessors().addAll(this.getPredecessors());
    }
    for (StringBuilderNode predecessor : this.getPredecessors()) {
      predecessor.getSuccessors().remove(this);
      predecessor.getSuccessors().addAll(this.getSuccessors());
    }
    isDead = true;
  }

  /** EscapeNode is used to explicitly define an escape point for a StringBuilder. */
  static class EscapeNode extends StringBuilderNode {

    @Override
    boolean isEscapeNode() {
      return true;
    }
  }

  /**
   * MutateNode defines if a string builder could be possibly mutated or inspected. An example could
   * be:
   *
   * <pre>
   * sb = new StringBuilder();
   * escape(sb);
   * sb.append("foo");
   * canMutate(); <-- This is represented by a MutateNode.
   * sb.append("bar");
   * </pre>
   */
  static class MutateNode extends StringBuilderNode {

    @Override
    boolean isMutateNode() {
      return true;
    }
  }

  /**
   * SplitReferenceNodes are synthetic nodes inserted when a string builder is used in multiple
   * successor blocks.
   */
  static class SplitReferenceNode extends StringBuilderNode {

    @Override
    boolean isSplitReferenceNode() {
      return true;
    }
  }

  /**
   * LoopNode is a node indicating that all successor paths are part of a loop. LoopNode's are only
   * inserted once ensuring there are no loops in a StringBuilderGraph.
   */
  static class LoopNode extends StringBuilderNode {

    @Override
    boolean isLoopNode() {
      return true;
    }
  }

  /** A NewInstanceNode is a new instance of either StringBuilder or StringBuffer. */
  static class NewInstanceNode extends StringBuilderNode implements StringBuilderInstruction {

    private final NewInstance instruction;

    private NewInstanceNode(NewInstance instruction) {
      this.instruction = instruction;
    }

    @Override
    boolean isNewInstanceNode() {
      return true;
    }

    @Override
    NewInstanceNode asNewInstanceNode() {
      return this;
    }

    @Override
    public Instruction getInstruction() {
      return instruction;
    }

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

    @Override
    public StringBuilderInstruction asStringBuilderInstructionNode() {
      return this;
    }
  }

  /** An initNode is where a StringBuilder/StringBuffer is initialized. */
  static class InitNode extends StringBuilderNode
      implements InitOrAppend, StringBuilderInstruction {

    private final InvokeDirect instruction;
    private ImplicitToStringNode implicitToStringNode;
    private String constantArgument;

    private InitNode(InvokeDirect instruction) {
      this.instruction = instruction;
    }

    @Override
    boolean isInitNode() {
      return true;
    }

    @Override
    boolean isInitOrAppend() {
      return true;
    }

    @Override
    InitNode asInitNode() {
      return this;
    }

    @Override
    InitOrAppend asInitOrAppend() {
      return this;
    }

    @Override
    public Instruction getInstruction() {
      return instruction;
    }

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

    @Override
    public StringBuilderInstruction asStringBuilderInstructionNode() {
      return this;
    }

    @Override
    public void setConstantArgument(String constantArgument) {
      this.constantArgument = constantArgument;
    }

    @Override
    public void setImplicitToStringNode(ImplicitToStringNode node) {
      implicitToStringNode = node;
    }

    @Override
    public ImplicitToStringNode getImplicitToStringNode() {
      return implicitToStringNode;
    }

    @Override
    public String getConstantArgument() {
      return constantArgument;
    }

    @Override
    public boolean hasConstantArgument() {
      return constantArgument != null;
    }
  }

  /** AppendNodes are StringBuilder.append or StringBuffer.append. */
  static class AppendNode extends StringBuilderNode
      implements InitOrAppend, StringBuilderInstruction {

    private final InvokeVirtual instruction;
    private ImplicitToStringNode implicitToStringNode;
    private String constantArgument;

    private AppendNode(InvokeVirtual instruction) {
      this.instruction = instruction;
    }

    @Override
    boolean isAppendNode() {
      return true;
    }

    @Override
    boolean isInitOrAppend() {
      return true;
    }

    @Override
    AppendNode asAppendNode() {
      return this;
    }

    @Override
    InitOrAppend asInitOrAppend() {
      return this;
    }

    @Override
    public Instruction getInstruction() {
      return instruction;
    }

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

    @Override
    public StringBuilderInstruction asStringBuilderInstructionNode() {
      return this;
    }

    @Override
    public void setConstantArgument(String constantArgument) {
      this.constantArgument = constantArgument;
    }

    @Override
    public void setImplicitToStringNode(ImplicitToStringNode node) {
      implicitToStringNode = node;
    }

    @Override
    public ImplicitToStringNode getImplicitToStringNode() {
      return implicitToStringNode;
    }

    @Override
    public String getConstantArgument() {
      return constantArgument;
    }

    @Override
    public boolean hasConstantArgument() {
      return constantArgument != null;
    }
  }

  /**
   * ToStringNodes marked a point where a StringBuilder/StringBuffer is materialized to a string.
   */
  static class ToStringNode extends StringBuilderNode implements StringBuilderInstruction {

    private final InvokeMethod instruction;

    private ToStringNode(InvokeMethod instruction) {
      this.instruction = instruction;
    }

    @Override
    boolean isToStringNode() {
      return true;
    }

    @Override
    ToStringNode asToStringNode() {
      return this;
    }

    @Override
    public Instruction getInstruction() {
      return instruction;
    }

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

    @Override
    public StringBuilderInstruction asStringBuilderInstructionNode() {
      return this;
    }
  }

  /**
   * InspectingNode is inserted if there is inspection of the capacity of a
   * StringBuilder/StringBuffer. Special care needs to be taken since we try to ensure that capacity
   * will be the same after optimizations.
   */
  static class InspectingNode extends StringBuilderNode implements StringBuilderInstruction {

    private final Instruction instruction;

    private InspectingNode(Instruction instruction) {
      this.instruction = instruction;
    }

    @Override
    boolean isInspectingNode() {
      return true;
    }

    @Override
    InspectingNode asInspectingNode() {
      return this;
    }

    @Override
    public Instruction getInstruction() {
      return instruction;
    }

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

    @Override
    public StringBuilderInstruction asStringBuilderInstructionNode() {
      return this;
    }
  }

  /** OtherStringBuilderNode marks operations on string builders we do not model. */
  static class OtherStringBuilderNode extends StringBuilderNode
      implements StringBuilderInstruction {

    private final Instruction instruction;

    private OtherStringBuilderNode(Instruction instruction) {
      this.instruction = instruction;
    }

    @Override
    boolean isOtherStringBuilderNode() {
      return true;
    }

    @Override
    OtherStringBuilderNode asOtherStringBuilderNode() {
      return this;
    }

    @Override
    public Instruction getInstruction() {
      return instruction;
    }

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

    @Override
    public StringBuilderInstruction asStringBuilderInstructionNode() {
      return this;
    }
  }

  /**
   * ImplicitToStringNode are placed when StringBuilder/StringBuffer is appended to another
   * StringBuilder/StringBuffer.
   */
  static class ImplicitToStringNode extends StringBuilderNode {

    private final InitOrAppend initOrAppend;

    ImplicitToStringNode(InitOrAppend initOrAppend) {
      this.initOrAppend = initOrAppend;
    }

    public InitOrAppend getInitOrAppend() {
      return initOrAppend;
    }

    @Override
    boolean isImplicitToStringNode() {
      return true;
    }

    @Override
    ImplicitToStringNode asImplicitToStringNode() {
      return this;
    }
  }

  static EscapeNode createEscapeNode() {
    return new EscapeNode();
  }

  static MutateNode createMutateNode() {
    return new MutateNode();
  }

  static SplitReferenceNode createSplitReferenceNode() {
    return new SplitReferenceNode();
  }

  static LoopNode createLoopNode() {
    return new LoopNode();
  }

  static NewInstanceNode createNewInstanceNode(NewInstance instruction) {
    return new NewInstanceNode(instruction);
  }

  static InitNode createInitNode(InvokeDirect instruction) {
    return new InitNode(instruction);
  }

  static AppendNode createAppendNode(InvokeVirtual instruction) {
    return new AppendNode(instruction);
  }

  static ToStringNode createToStringNode(InvokeMethod instruction) {
    return new ToStringNode(instruction);
  }

  static InspectingNode createInspectionNode(Instruction instruction) {
    return new InspectingNode(instruction);
  }

  static OtherStringBuilderNode createOtherStringBuilderNode(Instruction instruction) {
    return new OtherStringBuilderNode(instruction);
  }

  static ImplicitToStringNode createImplicitToStringNode(InitOrAppend otherNode) {
    return new ImplicitToStringNode(otherNode);
  }
}
