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

import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.Position;
import com.android.tools.r8.position.TextPosition;
import com.android.tools.r8.position.TextRange;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

public abstract class ProguardClassSpecification {

  public abstract static class
  Builder<C extends ProguardClassSpecification, B extends Builder<C, B>> {

    protected Origin origin;
    protected Position start;
    protected Position end;
    protected String source;
    private final ImmutableList.Builder<ProguardTypeMatcher> classAnnotations =
        ImmutableList.builder();
    protected ProguardAccessFlags classAccessFlags = new ProguardAccessFlags();
    protected ProguardAccessFlags negatedClassAccessFlags = new ProguardAccessFlags();
    protected boolean classTypeNegated = false;
    protected ProguardClassType classType = ProguardClassType.UNSPECIFIED;
    protected ProguardClassNameList classNames;
    private final ImmutableList.Builder<ProguardTypeMatcher> inheritanceAnnotations =
        ImmutableList.builder();
    protected ProguardTypeMatcher inheritanceClassName;
    protected boolean inheritanceIsExtends = false;
    // TODO(b/270398965): Replace LinkedList.
    @SuppressWarnings("JdkObsolete")
    protected List<ProguardMemberRule> memberRules = new LinkedList<>();

    protected Builder() {
      this(Origin.unknown(), Position.UNKNOWN);
    }

    protected Builder(Origin origin, Position start) {
      this.origin = origin;
      this.start = start;
    }

    public abstract C build();

    public abstract B self();

    public B setOrigin(Origin origin) {
      this.origin = origin;
      return self();
    }

    public B setStart(Position start) {
      this.start = start;
      return self();
    }

    public B setEnd(Position end) {
      this.end = end;
      return self();
    }

    public B setSource(String source) {
      this.source = source;
      return self();
    }

    public Position getPosition() {
      if (start == null) {
        return Position.UNKNOWN;
      }
      if (end == null || !((start instanceof TextPosition) && (end instanceof TextPosition))) {
        return start;
      }
      return new TextRange((TextPosition) start, (TextPosition) end);
    }

    public List<ProguardMemberRule> getMemberRules() {
      return memberRules;
    }

    public B setMemberRules(List<ProguardMemberRule> memberRules) {
      this.memberRules = memberRules;
      return self();
    }

    public boolean getInheritanceIsExtends() {
      return inheritanceIsExtends;
    }

    public B setInheritanceIsExtends(boolean inheritanceIsExtends) {
      this.inheritanceIsExtends = inheritanceIsExtends;
      return self();
    }

    public boolean hasInheritanceClassName() {
      return inheritanceClassName != null;
    }

    public ProguardTypeMatcher getInheritanceClassName() {
      return inheritanceClassName;
    }

    public B setInheritanceClassName(ProguardTypeMatcher inheritanceClassName) {
      this.inheritanceClassName = inheritanceClassName;
      return self();
    }

    public B addInheritanceAnnotations(List<ProguardTypeMatcher> inheritanceAnnotations) {
      assert inheritanceAnnotations != null;
      this.inheritanceAnnotations.addAll(inheritanceAnnotations);
      return self();
    }

    public List<ProguardTypeMatcher> buildInheritanceAnnotations() {
      return inheritanceAnnotations.build();
    }

    public ProguardClassNameList getClassNames() {
      return classNames;
    }

    public B setClassNames(ProguardClassNameList classNames) {
      this.classNames = classNames;
      return self();
    }

    public ProguardClassType getClassType() {
      return classType;
    }

    public B setClassType(ProguardClassType classType) {
      this.classType = classType;
      return self();
    }

    public boolean getClassTypeNegated() {
      return classTypeNegated;
    }

    public B setClassTypeNegated(boolean classTypeNegated) {
      this.classTypeNegated = classTypeNegated;
      return self();
    }

    public ProguardAccessFlags getClassAccessFlags() {
      return classAccessFlags;
    }

    public B setClassAccessFlags(ProguardAccessFlags flags) {
      classAccessFlags = flags;
      return self();
    }

    public ProguardAccessFlags getNegatedClassAccessFlags() {
      return negatedClassAccessFlags;
    }

    public B setNegatedClassAccessFlags(ProguardAccessFlags flags) {
      negatedClassAccessFlags = flags;
      return self();
    }

    public B addClassAnnotation(ProguardTypeMatcher classAnnotation) {
      classAnnotations.add(classAnnotation);
      return self();
    }

    public B addClassAnnotations(List<ProguardTypeMatcher> classAnnotations) {
      assert classAnnotations != null;
      this.classAnnotations.addAll(classAnnotations);
      return self();
    }

    public List<ProguardTypeMatcher> buildClassAnnotations() {
      return classAnnotations.build();
    }

    protected void matchAllSpecification() {
      setClassNames(ProguardClassNameList.singletonList(ProguardTypeMatcher.defaultAllMatcher()));
      setMemberRules(ImmutableList.of(ProguardMemberRule.defaultKeepAllRule()));
    }
  }

  private final Origin origin;
  private final Position position;
  private final String source;
  private final List<ProguardTypeMatcher> classAnnotations;
  private final ProguardAccessFlags classAccessFlags;
  private final ProguardAccessFlags negatedClassAccessFlags;
  private final boolean classTypeNegated;
  private final ProguardClassType classType;
  private final ProguardClassNameList classNames;
  private final List<ProguardTypeMatcher> inheritanceAnnotations;
  private final ProguardTypeMatcher inheritanceClassName;
  private final boolean inheritanceIsExtends;
  private final List<ProguardMemberRule> memberRules;

  protected ProguardClassSpecification(
      Origin origin,
      Position position,
      String source,
      List<ProguardTypeMatcher> classAnnotations,
      ProguardAccessFlags classAccessFlags,
      ProguardAccessFlags negatedClassAccessFlags,
      boolean classTypeNegated,
      ProguardClassType classType,
      ProguardClassNameList classNames,
      List<ProguardTypeMatcher> inheritanceAnnotations,
      ProguardTypeMatcher inheritanceClassName,
      boolean inheritanceIsExtends,
      List<ProguardMemberRule> memberRules) {
    assert origin != null;
    assert position != null;
    assert source != null || origin != Origin.unknown();
    this.origin = origin;
    this.position = position;
    this.source = source;
    this.classAnnotations = classAnnotations;
    this.classAccessFlags = classAccessFlags;
    this.negatedClassAccessFlags = negatedClassAccessFlags;
    this.classTypeNegated = classTypeNegated;
    this.classType = classType;
    assert classType != null;
    this.classNames = classNames;
    this.inheritanceAnnotations = inheritanceAnnotations;
    this.inheritanceClassName = inheritanceClassName;
    this.inheritanceIsExtends = inheritanceIsExtends;
    this.memberRules = memberRules;
  }

  public Origin getOrigin() {
    return origin;
  }

  public Position getPosition() {
    return position;
  }

  public String getSource() {
    return source;
  }

  public List<ProguardMemberRule> getMemberRules() {
    return memberRules;
  }

  public boolean getInheritanceIsExtends() {
    return inheritanceIsExtends;
  }

  public boolean getInheritanceIsImplements() {
    return !inheritanceIsExtends;
  }

  public boolean hasInheritanceClassName() {
    return inheritanceClassName != null;
  }

  public ProguardTypeMatcher getInheritanceClassName() {
    return inheritanceClassName;
  }

  public List<ProguardTypeMatcher> getInheritanceAnnotations() {
    return inheritanceAnnotations;
  }

  public ProguardClassNameList getClassNames() {
    return classNames;
  }

  public ProguardClassType getClassType() {
    return classType;
  }

  public boolean getClassTypeNegated() {
    return classTypeNegated;
  }

  public ProguardAccessFlags getClassAccessFlags() {
    return classAccessFlags;
  }

  public ProguardAccessFlags getNegatedClassAccessFlags() {
    return negatedClassAccessFlags;
  }

  public List<ProguardTypeMatcher> getClassAnnotations() {
    return classAnnotations;
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof ProguardClassSpecification)) {
      return false;
    }
    ProguardClassSpecification that = (ProguardClassSpecification) o;

    if (classTypeNegated != that.classTypeNegated) {
      return false;
    }
    if (inheritanceIsExtends != that.inheritanceIsExtends) {
      return false;
    }
    if (!Objects.equals(classAnnotations, that.classAnnotations)) {
      return false;
    }
    if (!classAccessFlags.equals(that.classAccessFlags)) {
      return false;
    }
    if (!negatedClassAccessFlags.equals(that.negatedClassAccessFlags)) {
      return false;
    }
    if (classType != that.classType) {
      return false;
    }
    if (!classNames.equals(that.classNames)) {
      return false;
    }
    if (!Objects.equals(inheritanceAnnotations, that.inheritanceAnnotations)) {
      return false;
    }
    if (!Objects.equals(inheritanceClassName, that.inheritanceClassName)) {
      return false;
    }
    return memberRules.equals(that.memberRules);
  }

  @Override
  public int hashCode() {
    // Used multiplier 3 to avoid too much overflow when computing hashCode.
    int result = classAnnotations.hashCode();
    result = 3 * result + classAccessFlags.hashCode();
    result = 3 * result + negatedClassAccessFlags.hashCode();
    result = 3 * result + (classTypeNegated ? 1 : 0);
    result = 3 * result + (classType != null ? classType.hashCode() : 0);
    result = 3 * result + classNames.hashCode();
    result = 3 * result + inheritanceAnnotations.hashCode();
    result = 3 * result + (inheritanceClassName != null ? inheritanceClassName.hashCode() : 0);
    result = 3 * result + (inheritanceIsExtends ? 1 : 0);
    result = 3 * result + memberRules.hashCode();
    return result;
  }

  protected StringBuilder append(StringBuilder builder) {
    appendAnnotations(classAnnotations, builder);
    boolean needsSpaceBeforeClassType =
        StringUtils.appendNonEmpty(builder, null, classAccessFlags, null)
            | StringUtils.appendNonEmpty(
                builder, "!", negatedClassAccessFlags.toString().replace(" ", " !"), null);
    if (needsSpaceBeforeClassType) {
      builder.append(' ');
    }
    if (classTypeNegated) {
      builder.append('!');
    }
    builder.append(classType);
    builder.append(' ');
    classNames.writeTo(builder);
    if (hasInheritanceClassName()) {
      builder.append(' ').append(inheritanceIsExtends ? "extends" : "implements").append(' ');
      appendAnnotations(inheritanceAnnotations, builder);
      builder.append(inheritanceClassName);
    }
    if (!memberRules.isEmpty()) {
      builder.append(" {").append(System.lineSeparator());
      memberRules.forEach(memberRule -> {
        builder.append("  ");
        builder.append(memberRule);
        builder.append(";").append(System.lineSeparator());
      });
      builder.append("}");
    }
    return builder;
  }

  private static void appendAnnotations(
      List<ProguardTypeMatcher> annotations, StringBuilder builder) {
    if (!annotations.isEmpty()) {
      Iterator<ProguardTypeMatcher> annotationIterator = annotations.iterator();
      builder.append('@').append(annotationIterator.next());
      while (annotationIterator.hasNext()) {
        builder.append(" @").append(annotationIterator.next());
      }
      builder.append(' ');
    }
  }

  @Override
  public String toString() {
    return append(new StringBuilder()).toString();
  }
}
