// 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.keepanno.ast;

import java.util.Objects;

/**
 * An edge in the keep graph.
 *
 * <p>An edge describes a set of preconditions and a set of consequences. If the preconditions are
 * met, then the consequences are put into effect.
 *
 * <p>Below is a BNF of the keep edge AST for reference. The non-terminals are written in ALL_CAPS,
 * possibly-empty repeatable subexpressions denoted with SUB* and non-empty with SUB+
 *
 * <p>In the Java AST, the non-terminals are prefixed with 'Keep' and in CamelCase.
 *
 * <p>TODO(b/248408342): Update the BNF and AST to be complete.
 *
 * <pre>
 *   EDGE ::= METAINFO BINDINGS PRECONDITIONS -> CONSEQUENCES
 *   METAINFO ::= [CONTEXT] [DESCRIPTION]
 *   CONTEXT ::= class-descriptor | method-descriptor | field-descriptor
 *   DESCRIPTION ::= string-content
 *
 *   BINDINGS ::= (BINDING_NAME = ITEM_PATTERN)*
 *   BINDING_NAME ::= string-content
 *   BINDING_REFERENCE ::= BINDING_NAME
 *
 *   PRECONDITIONS ::= always | CONDITION+
 *   CONDITION ::= ITEM_REFERENCE
 *
 *   CONSEQUENCES ::= TARGET+
 *   TARGET ::= OPTIONS ITEM_REFERENCE
 *   OPTIONS ::= keep-all | OPTION+
 *   OPTION ::= shrinking | optimizing | obfuscating | access-modification | annotation-removal
 *
 *   ITEM_REFERENCE  ::= BINDING_REFERENCE | ITEM_PATTERN
 *   CLASS_REFERENCE ::= BINDING_REFERENCE | QUALIFIED_CLASS_NAME_PATTERN
 *
 *   ITEM_PATTERN
 *     ::= any
 *       | class CLASS_REFERENCE extends EXTENDS_PATTERN { MEMBER_PATTERN }
 *
 *   TYPE_PATTERN ::= any | exact type-descriptor
 *   PACKAGE_PATTERN ::= any | exact package-name
 *
 *   QUALIFIED_CLASS_NAME_PATTERN
 *     ::= any
 *       | PACKAGE_PATTERN UNQUALIFIED_CLASS_NAME_PATTERN
 *       | BINDING_REFERENCE
 *
 *   UNQUALIFIED_CLASS_NAME_PATTERN ::= any | exact simple-class-name
 *
 *   EXTENDS_PATTERN ::= any | QUALIFIED_CLASS_NAME_PATTERN
 *
 *   MEMBER_PATTERN ::= none | all | FIELD_PATTERN | METHOD_PATTERN
 *
 *   FIELD_PATTERN
 *     ::= FIELD_ACCESS_PATTERN
 *           FIELD_TYPE_PATTERN
 *           FIELD_NAME_PATTERN;
 *
 *   METHOD_PATTERN
 *     ::= METHOD_ACCESS_PATTERN
 *           METHOD_RETURN_TYPE_PATTERN
 *           METHOD_NAME_PATTERN
 *           METHOD_PARAMETERS_PATTERN
 *
 *   METHOD_ACCESS_PATTERN ::= any
 *   METHOD_NAME_PATTERN ::= any | exact method-name
 *   METHOD_RETURN_TYPE_PATTERN ::= void | TYPE_PATTERN
 *   METHOD_PARAMETERS_PATTERN ::= any | none | (TYPE_PATTERN+)
 * </pre>
 */
public final class KeepEdge {

  public static class Builder {
    private KeepEdgeMetaInfo metaInfo = KeepEdgeMetaInfo.none();
    private KeepBindings bindings = KeepBindings.none();
    private KeepPreconditions preconditions = KeepPreconditions.always();
    private KeepConsequences consequences;

    private Builder() {}

    public Builder setMetaInfo(KeepEdgeMetaInfo metaInfo) {
      this.metaInfo = metaInfo;
      return this;
    }

    public Builder setBindings(KeepBindings bindings) {
      this.bindings = bindings;
      return this;
    }

    public Builder setPreconditions(KeepPreconditions preconditions) {
      this.preconditions = preconditions;
      return this;
    }

    public Builder setConsequences(KeepConsequences consequences) {
      this.consequences = consequences;
      return this;
    }

    public KeepEdge build() {
      if (consequences.isEmpty()) {
        throw new KeepEdgeException("KeepEdge must have non-empty set of consequences.");
      }
      return new KeepEdge(metaInfo, bindings, preconditions, consequences);
    }
  }

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

  private final KeepEdgeMetaInfo metaInfo;
  private final KeepBindings bindings;
  private final KeepPreconditions preconditions;
  private final KeepConsequences consequences;

  private KeepEdge(
      KeepEdgeMetaInfo metaInfo,
      KeepBindings bindings,
      KeepPreconditions preconditions,
      KeepConsequences consequences) {
    assert metaInfo != null;
    assert bindings != null;
    assert preconditions != null;
    assert consequences != null;
    this.metaInfo = metaInfo;
    this.bindings = bindings;
    this.preconditions = preconditions;
    this.consequences = consequences;
  }

  public KeepEdgeMetaInfo getMetaInfo() {
    return metaInfo;
  }

  public KeepBindings getBindings() {
    return bindings;
  }

  public KeepPreconditions getPreconditions() {
    return preconditions;
  }

  public KeepConsequences getConsequences() {
    return consequences;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    KeepEdge keepEdge = (KeepEdge) o;
    return preconditions.equals(keepEdge.preconditions)
        && consequences.equals(keepEdge.consequences);
  }

  @Override
  public int hashCode() {
    return Objects.hash(preconditions, consequences);
  }

  @Override
  public String toString() {
    return "KeepEdge{" + "preconditions=" + preconditions + ", consequences=" + consequences + '}';
  }
}
