// 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 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 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);
    signature = update(signature, SIGNATURE, 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);
    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, ProguardConfiguration.Builder compatibility) {
    if (forceProguardCompatibility && innerClasses != enclosingMethod) {
      // If only one is true set both to true in Proguard compatibility mode.
      enclosingMethod = true;
      innerClasses = true;
      compatibility.addKeepAttributePatterns(
          ImmutableList.of(
              ProguardKeepAttributes.INNER_CLASSES,
              ProguardKeepAttributes.ENCLOSING_METHOD));
    }
    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.");
    } else if (signature && !innerClasses) {
      throw new CompilationError("Attribute Signature requires InnerClasses attribute. Check "
          + "-keepattributes directive.");
    }
    if (forceProguardCompatibility && localVariableTable && !lineNumberTable) {
      // If locals are kept, assume line numbers should be kept too.
      lineNumberTable = true;
      compatibility.addKeepAttributePatterns(
          ImmutableList.of(ProguardKeepAttributes.LINE_NUMBER_TABLE));
    }
    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.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);
  }

  public boolean isEmpty() {
    return !sourceFile
        && !sourceDir
        && !innerClasses
        && !enclosingMethod
        && !signature
        && !exceptions
        && !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 (sourceDebugExtension) {
      attributes.add(SOURCE_DEBUG_EXTENSION);
    }
    if (runtimeVisibleAnnotations) {
      attributes.add(RUNTIME_INVISIBLE_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();
  }
}
