// 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;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * A pattern for matching items in the program.
 *
 * <p>An item pattern can be any item, or it can describe a family of classes or a family of members
 * on a classes.
 *
 * <p>A pattern cannot describe both a class *and* a member of a class. Either it is a pattern on
 * classes or it is a pattern on members. The distinction is defined by having a "none" member
 * pattern.
 */
public abstract class KeepItemPattern {

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

  public static KeepItemPattern any() {
    return KeepItemAnyPattern.getInstance();
  }

  public static class Builder {

    private KeepQualifiedClassNamePattern classNamePattern;
    private KeepExtendsPattern extendsPattern = KeepExtendsPattern.any();
    private KeepMembersPattern membersPattern = KeepMembersPattern.none();

    private Builder() {}

    public Builder any() {
      classNamePattern = KeepQualifiedClassNamePattern.any();
      extendsPattern = KeepExtendsPattern.any();
      membersPattern = KeepMembersPattern.all();
      return this;
    }

    public Builder setClassPattern(KeepQualifiedClassNamePattern qualifiedClassNamePattern) {
      this.classNamePattern = qualifiedClassNamePattern;
      return this;
    }

    public Builder setExtendsPattern(KeepExtendsPattern extendsPattern) {
      this.extendsPattern = extendsPattern;
      return this;
    }

    public Builder setMembersPattern(KeepMembersPattern membersPattern) {
      this.membersPattern = membersPattern;
      return this;
    }

    public KeepItemPattern build() {
      if (classNamePattern == null) {
        throw new KeepEdgeException("Class pattern must define a class name pattern.");
      }
      if (classNamePattern.isAny() && extendsPattern.isAny() && membersPattern.isAll()) {
        return KeepItemPattern.any();
      }
      return new KeepClassPattern(classNamePattern, extendsPattern, membersPattern);
    }
  }

  private static class KeepItemAnyPattern extends KeepItemPattern {

    private static KeepItemAnyPattern INSTANCE = null;

    public static KeepItemAnyPattern getInstance() {
      if (INSTANCE == null) {
        INSTANCE = new KeepItemAnyPattern();
      }
      return INSTANCE;
    }

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

    @Override
    public <T> T match(Supplier<T> onAny, Function<KeepClassPattern, T> onItem) {
      return onAny.get();
    }

    @Override
    public boolean equals(Object obj) {
      return this == obj;
    }

    @Override
    public int hashCode() {
      return System.identityHashCode(this);
    }

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

  public static class KeepClassPattern extends KeepItemPattern {

    private final KeepQualifiedClassNamePattern qualifiedClassPattern;
    private final KeepExtendsPattern extendsPattern;
    private final KeepMembersPattern membersPattern;
    // TODO: class annotations

    private KeepClassPattern(
        KeepQualifiedClassNamePattern qualifiedClassPattern,
        KeepExtendsPattern extendsPattern,
        KeepMembersPattern membersPattern) {
      assert qualifiedClassPattern != null;
      assert extendsPattern != null;
      assert membersPattern != null;
      this.qualifiedClassPattern = qualifiedClassPattern;
      this.extendsPattern = extendsPattern;
      this.membersPattern = membersPattern;
    }

    @Override
    public boolean isAny() {
      return qualifiedClassPattern.isAny() && extendsPattern.isAny() && membersPattern.isAll();
    }

    @Override
    public <T> T match(Supplier<T> onAny, Function<KeepClassPattern, T> onItem) {
      if (isAny()) {
        return onAny.get();
      } else {
        return onItem.apply(this);
      }
    }

    public KeepQualifiedClassNamePattern getClassNamePattern() {
      return qualifiedClassPattern;
    }

    public KeepExtendsPattern getExtendsPattern() {
      return extendsPattern;
    }

    public KeepMembersPattern getMembersPattern() {
      return membersPattern;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null || getClass() != obj.getClass()) {
        return false;
      }
      KeepClassPattern that = (KeepClassPattern) obj;
      return qualifiedClassPattern.equals(that.qualifiedClassPattern)
          && extendsPattern.equals(that.extendsPattern)
          && membersPattern.equals(that.membersPattern);
    }

    @Override
    public int hashCode() {
      return Objects.hash(qualifiedClassPattern, extendsPattern, membersPattern);
    }

    @Override
    public String toString() {
      return "KeepClassPattern{"
          + "qualifiedClassPattern="
          + qualifiedClassPattern
          + ", extendsPattern="
          + extendsPattern
          + ", membersPattern="
          + membersPattern
          + '}';
    }
  }

  public abstract boolean isAny();

  public abstract <T> T match(Supplier<T> onAny, Function<KeepClassPattern, T> onItem);
}
