// Copyright (c) 2023, 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.keeprules;

import com.android.tools.r8.keepanno.ast.KeepBindings;
import com.android.tools.r8.keepanno.ast.KeepClassReference;
import com.android.tools.r8.keepanno.ast.KeepCondition;
import com.android.tools.r8.keepanno.ast.KeepConsequences;
import com.android.tools.r8.keepanno.ast.KeepEdge;
import com.android.tools.r8.keepanno.ast.KeepItemKind;
import com.android.tools.r8.keepanno.ast.KeepItemPattern;
import com.android.tools.r8.keepanno.ast.KeepItemReference;
import com.android.tools.r8.keepanno.ast.KeepPreconditions;
import com.android.tools.r8.keepanno.ast.KeepTarget;
import java.util.ArrayList;
import java.util.List;

/**
 * Normalize a keep edge with respect to its bindings. This will systematically introduce a binding
 * for each item in the edge. It will also introduce a class binding for the holder of any member
 * item. By introducing a binding for each item the binding can be used as item identity.
 */
public class KeepEdgeNormalizer {

  private static final String syntheticBindingPrefix = "SyntheticBinding";
  private static final char syntheticBindingSuffix = 'X';

  public static KeepEdge normalize(KeepEdge edge) {
    // Check that all referenced bindings are defined.
    KeepEdgeNormalizer normalizer = new KeepEdgeNormalizer(edge);
    KeepEdge normalized = normalizer.run();
    KeepEdge minimized = KeepEdgeBindingMinimizer.run(normalized);
    return minimized;
  }

  private final KeepEdge edge;

  private String freshBindingNamePrefix;
  private int nextFreshBindingNameIndex = 1;

  private final KeepBindings.Builder bindingsBuilder = KeepBindings.builder();
  private final KeepPreconditions.Builder preconditionsBuilder = KeepPreconditions.builder();
  private final KeepConsequences.Builder consequencesBuilder = KeepConsequences.builder();

  private KeepEdgeNormalizer(KeepEdge edge) {
    this.edge = edge;
    findValidFreshBindingPrefix();
  }

  private void findValidFreshBindingPrefix() {
    List<String> existingSuffixes = new ArrayList<>();
    edge.getBindings()
        .forEach(
            (name, ignore) -> {
              if (name.startsWith(syntheticBindingPrefix)) {
                existingSuffixes.add(name.substring(syntheticBindingPrefix.length()));
              }
            });
    if (!existingSuffixes.isEmpty()) {
      int suffixLength = 0;
      for (String existingSuffix : existingSuffixes) {
        suffixLength = Math.max(suffixLength, getRepeatedSuffixLength(existingSuffix));
      }
      StringBuilder suffix = new StringBuilder();
      for (int i = 0; i <= suffixLength; i++) {
        suffix.append(syntheticBindingSuffix);
      }
      freshBindingNamePrefix = syntheticBindingPrefix + suffix;
    } else {
      freshBindingNamePrefix = syntheticBindingPrefix;
    }
  }

  private int getRepeatedSuffixLength(String string) {
    int i = 0;
    while (i < string.length() && string.charAt(i) == syntheticBindingSuffix) {
      i++;
    }
    return i;
  }

  private String nextFreshBindingName() {
    return freshBindingNamePrefix + (nextFreshBindingNameIndex++);
  }

  private KeepEdge run() {
    edge.getBindings()
        .forEach(
            (name, pattern) -> {
              bindingsBuilder.addBinding(name, normalizeItemPattern(pattern));
            });
    // TODO(b/248408342): Normalize the preconditions by identifying vacuously true conditions.
    edge.getPreconditions()
        .forEach(
            condition ->
                preconditionsBuilder.addCondition(
                    KeepCondition.builder()
                        .setItemReference(normalizeItem(condition.getItem()))
                        .build()));
    edge.getConsequences()
        .forEachTarget(
            target -> {
              consequencesBuilder.addTarget(
                  KeepTarget.builder()
                      .setOptions(target.getOptions())
                      .setItemReference(normalizeItem(target.getItem()))
                      .build());
            });
    return KeepEdge.builder()
        .setMetaInfo(edge.getMetaInfo())
        .setBindings(bindingsBuilder.build())
        .setPreconditions(preconditionsBuilder.build())
        .setConsequences(consequencesBuilder.build())
        .build();
  }

  private KeepItemReference normalizeItem(KeepItemReference item) {
    if (item.isBindingReference()) {
      return item;
    }
    KeepItemPattern newItemPattern = normalizeItemPattern(item.asItemPattern());
    String bindingName = nextFreshBindingName();
    bindingsBuilder.addBinding(bindingName, newItemPattern);
    return KeepItemReference.fromBindingReference(bindingName);
  }

  private KeepItemPattern normalizeItemPattern(KeepItemPattern pattern) {
    // If the pattern is just a class pattern it is in normal form.
    if (pattern.isClassItemPattern()) {
      return pattern;
    }
    KeepClassReference bindingReference = bindingForClassItem(pattern);
    return getMemberItemPattern(pattern, bindingReference);
  }

  private KeepClassReference bindingForClassItem(KeepItemPattern pattern) {
    KeepClassReference classReference = pattern.getClassReference();
    if (classReference.isBindingReference()) {
      // If the class is already defined via a binding then no need to introduce a new one and
      // change the item.
      return classReference;
    }
    String bindingName = nextFreshBindingName();
    KeepClassReference bindingReference = KeepClassReference.fromBindingReference(bindingName);
    KeepItemPattern newClassPattern = getClassItemPattern(pattern);
    bindingsBuilder.addBinding(bindingName, newClassPattern);
    return bindingReference;
  }

  private KeepItemPattern getClassItemPattern(KeepItemPattern fromPattern) {
    return KeepItemPattern.builder()
        .setClassReference(fromPattern.getClassReference())
        .setExtendsPattern(fromPattern.getExtendsPattern())
        .build();
  }

  private KeepItemPattern getMemberItemPattern(
      KeepItemPattern fromPattern, KeepClassReference classReference) {
    assert fromPattern.getKind().equals(KeepItemKind.ONLY_MEMBERS)
        || fromPattern.getKind().equals(KeepItemKind.CLASS_AND_MEMBERS);
    return KeepItemPattern.builder()
        .setKind(fromPattern.getKind())
        .setClassReference(classReference)
        .setMemberPattern(fromPattern.getMemberPattern())
        .build();
  }
}
