// 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.errors.CompilationError;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;

public class ProguardKeepAttributes {

  public static final String SOURCE_FILE = "SourceFile";
  public static final String SOURCE_DIR = "SourceDir";
  public static final String INNER_CLASSES = "InnerClasses";
  public static final String ENCLOSING_METHOD = "EnclosingMethod";
  public static final String SIGNATURE = "Signature";
  public static final String EXCEPTIONS = "Exceptions";
  public static final String LINE_NUMBER_TABLE = "LineNumberTable";
  public static final String LOCAL_VARIABLE_TABLE = "LocalVariableTable";
  public static final String LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable";
  public static final String METHOD_PARAMETERS = "MethodParameters";
  public static final String SOURCE_DEBUG_EXTENSION = "SourceDebugExtension";
  public static final String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
  public static final String RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations";
  public static final String RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS =
      "RuntimeVisibleParameterAnnotations";
  public static final String RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS =
      "RuntimeInvisibleParameterAnnotations";
  public static final String RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations";
  public static final String RUNTIME_INVISIBLE_TYPE_ANNOTATIONS =
      "RuntimeInvisibleTypeAnnotations";
  public static final String ANNOTATION_DEFAULT = "AnnotationDefault";
  public static final String STACK_MAP_TABLE = "StackMapTable";

  public static final List<String> KEEP_ALL = ImmutableList.of("*");

  public boolean sourceFile = false;
  public boolean sourceDir = false;
  public boolean innerClasses = false;
  public boolean enclosingMethod = false;
  public boolean signature = false;
  public boolean exceptions = false;
  public boolean lineNumberTable = false;
  public boolean localVariableTable = false;
  public boolean localVariableTypeTable = false;
  public boolean methodParameters = false;
  public boolean sourceDebugExtension = false;
  public boolean runtimeVisibleAnnotations = false;
  public boolean runtimeInvisibleAnnotations = false;
  public boolean runtimeVisibleParameterAnnotations = false;
  public boolean runtimeInvisibleParameterAnnotations = false;
  public boolean runtimeVisibleTypeAnnotations = false;
  public boolean runtimeInvisibleTypeAnnotations = false;
  public boolean annotationDefault = false;
  public boolean stackMapTable = false;

  private ProguardKeepAttributes() {
  }

  public static ProguardKeepAttributes filterOnlySignatures() {
    ProguardKeepAttributes result = new ProguardKeepAttributes();
    result.applyPatterns(KEEP_ALL);
    result.signature = false;
    return result;
  }

  /**
   * Implements ProGuards attribute matching rules.
   *
   * @see <a href="https://www.guardsquare.com/en/proguard/manual/attributes">ProGuard manual</a>.
   */
  private boolean update(boolean previous, String text, List<String> patterns) {
    for (String pattern : patterns) {
      if (previous) {
        return true;
      }
      if (pattern.length() > 0 && pattern.charAt(0) == '!') {
        if (matches(pattern, 1, text, 0)) {
          break;
        }
      } else {
        previous = matches(pattern, 0, text, 0);
      }
    }
    return previous;
  }

  private boolean matches(String pattern, int patternPos, String text, int textPos) {
    while (patternPos < pattern.length()) {
      char next = pattern.charAt(patternPos++);
      if (next == '*') {
        while (textPos < text.length()) {
          if (matches(pattern, patternPos, text, textPos++)) {
            return true;
          }
        }
        return patternPos >= pattern.length();
      } else {
        if (textPos >= text.length() || text.charAt(textPos) != next) {
          return false;
        }
        textPos++;
      }
    }
    return textPos == text.length();
  }

  public static ProguardKeepAttributes fromPatterns(List<String> patterns) {
    ProguardKeepAttributes keepAttributes = new ProguardKeepAttributes();
    keepAttributes.applyPatterns(patterns);
    return keepAttributes;
  }

  public void applyPatterns(List<String> patterns) {
    sourceFile = update(sourceFile, SOURCE_FILE, patterns);
    sourceDir = update(sourceDir, SOURCE_DIR, patterns);
    innerClasses = update(innerClasses, INNER_CLASSES, patterns);
    enclosingMethod = update(enclosingMethod, ENCLOSING_METHOD, patterns);
    lineNumberTable = update(lineNumberTable, LINE_NUMBER_TABLE, patterns);
    localVariableTable = update(localVariableTable, LOCAL_VARIABLE_TABLE, patterns);
    localVariableTypeTable = update(localVariableTypeTable, LOCAL_VARIABLE_TYPE_TABLE, patterns);
    exceptions = update(exceptions, EXCEPTIONS, patterns);
    methodParameters = update(methodParameters, METHOD_PARAMETERS, patterns);
    signature = update(signature, SIGNATURE, patterns);
    sourceDebugExtension = update(sourceDebugExtension, SOURCE_DEBUG_EXTENSION, patterns);
    runtimeVisibleAnnotations = update(runtimeVisibleAnnotations, RUNTIME_VISIBLE_ANNOTATIONS,
        patterns);
    runtimeInvisibleAnnotations = update(runtimeInvisibleAnnotations,
        RUNTIME_INVISIBLE_ANNOTATIONS, patterns);
    runtimeVisibleParameterAnnotations = update(runtimeVisibleParameterAnnotations,
        RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, patterns);
    runtimeInvisibleParameterAnnotations = update(runtimeInvisibleParameterAnnotations,
        RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, patterns);
    runtimeVisibleTypeAnnotations = update(runtimeVisibleTypeAnnotations,
        RUNTIME_VISIBLE_TYPE_ANNOTATIONS, patterns);
    runtimeInvisibleTypeAnnotations = update(runtimeInvisibleTypeAnnotations,
        RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, patterns);
    annotationDefault = update(annotationDefault, ANNOTATION_DEFAULT, patterns);
    stackMapTable = update(stackMapTable, STACK_MAP_TABLE, patterns);
  }

  public void ensureValid(boolean forceProguardCompatibility) {
    if (forceProguardCompatibility && innerClasses != enclosingMethod) {
      // If only one is true set both to true in Proguard compatibility mode.
      enclosingMethod = true;
      innerClasses = true;
    }
    if (innerClasses && !enclosingMethod) {
      throw new CompilationError("Attribute InnerClasses requires EnclosingMethod attribute. "
          + "Check -keepattributes directive.");
    } else if (!innerClasses && enclosingMethod) {
      throw new CompilationError("Attribute EnclosingMethod requires InnerClasses attribute. "
          + "Check -keepattributes directive.");
    }
    if (forceProguardCompatibility && localVariableTable && !lineNumberTable) {
      // If locals are kept, assume line numbers should be kept too.
      lineNumberTable = true;
    }
    if (localVariableTable && !lineNumberTable) {
      throw new CompilationError(
          "Attribute " + LOCAL_VARIABLE_TABLE
              + " requires " + LINE_NUMBER_TABLE
              + ". Check -keepattributes directive.");
    }
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof ProguardKeepAttributes)) {
      return false;
    }
    ProguardKeepAttributes other = (ProguardKeepAttributes) o;
    return this.sourceFile == other.sourceFile
        && this.sourceDir == other.sourceDir
        && this.innerClasses == other.innerClasses
        && this.enclosingMethod == other.enclosingMethod
        && this.signature == other.signature
        && this.exceptions == other.exceptions
        && this.methodParameters == other.methodParameters
        && this.sourceDebugExtension == other.sourceDebugExtension
        && this.runtimeVisibleAnnotations == other.runtimeVisibleAnnotations
        && this.runtimeInvisibleAnnotations == other.runtimeInvisibleAnnotations
        && this.runtimeVisibleParameterAnnotations == other.runtimeVisibleParameterAnnotations
        && this.runtimeInvisibleParameterAnnotations == other.runtimeInvisibleParameterAnnotations
        && this.runtimeVisibleTypeAnnotations == other.runtimeVisibleTypeAnnotations
        && this.runtimeInvisibleTypeAnnotations == other.runtimeInvisibleTypeAnnotations
        && this.annotationDefault == other.annotationDefault
        && this.stackMapTable == other.stackMapTable;
  }

  @Override
  public int hashCode() {
    return (this.sourceFile ? 1 : 0)
        + (this.sourceDir ? 1 << 1 : 0)
        + (this.innerClasses ? 1 << 2 : 0)
        + (this.enclosingMethod ? 1 << 3 : 0)
        + (this.signature ? 1 << 4 : 0)
        + (this.exceptions ? 1 << 5 : 0)
        + (this.sourceDebugExtension ? 1 << 6 : 0)
        + (this.runtimeVisibleAnnotations ? 1 << 7 : 0)
        + (this.runtimeInvisibleAnnotations ? 1 << 8 : 0)
        + (this.runtimeVisibleParameterAnnotations ? 1 << 9 : 0)
        + (this.runtimeInvisibleParameterAnnotations ? 1 << 10 : 0)
        + (this.runtimeVisibleTypeAnnotations ? 1 << 11 : 0)
        + (this.runtimeInvisibleTypeAnnotations ? 1 << 12 : 0)
        + (this.annotationDefault ? 1 << 13 : 0)
        + (this.stackMapTable ? 1 << 14 : 0)
        + (this.methodParameters ? 1 << 15 : 0);
  }

  public boolean isEmpty() {
    return !sourceFile
        && !sourceDir
        && !innerClasses
        && !enclosingMethod
        && !signature
        && !exceptions
        && !methodParameters
        && !sourceDebugExtension
        && !runtimeVisibleAnnotations
        && !runtimeInvisibleAnnotations
        && !runtimeVisibleParameterAnnotations
        && !runtimeInvisibleParameterAnnotations
        && !runtimeVisibleTypeAnnotations
        && !runtimeInvisibleTypeAnnotations
        && !annotationDefault
        && !stackMapTable;
  }

  public StringBuilder append(StringBuilder builder) {
    List<String> attributes = new ArrayList<>();
    if (sourceFile) {
      attributes.add(SOURCE_FILE);
    }
    if (sourceDir) {
      attributes.add(SOURCE_DIR);
    }
    if (innerClasses) {
      attributes.add(INNER_CLASSES);
    }
    if (enclosingMethod) {
      attributes.add(ENCLOSING_METHOD);
    }
    if (signature) {
      attributes.add(SIGNATURE);
    }
    if (exceptions) {
      attributes.add(EXCEPTIONS);
    }
    if (methodParameters) {
      attributes.add(METHOD_PARAMETERS);
    }
    if (sourceDebugExtension) {
      attributes.add(SOURCE_DEBUG_EXTENSION);
    }
    if (runtimeVisibleAnnotations) {
      attributes.add(RUNTIME_VISIBLE_ANNOTATIONS);
    }
    if (runtimeInvisibleAnnotations) {
      attributes.add(RUNTIME_INVISIBLE_ANNOTATIONS);
    }
    if (runtimeVisibleParameterAnnotations) {
      attributes.add(RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS);
    }
    if (runtimeInvisibleParameterAnnotations) {
      attributes.add(RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS);
    }
    if (runtimeVisibleTypeAnnotations) {
      attributes.add(RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
    }
    if (runtimeInvisibleTypeAnnotations) {
      attributes.add(RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
    }
    if (annotationDefault) {
      attributes.add(ANNOTATION_DEFAULT);
    }
    if (stackMapTable) {
      attributes.add(STACK_MAP_TABLE);
    }

    if (attributes.size() > 0) {
      builder.append("-keepattributes ");
      builder.append(String.join(",", attributes));
    }

    return builder;
  }

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