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

import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Pair;
import com.google.common.collect.Sets;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public abstract class CodeToKeep {

  static CodeToKeep createCodeToKeep(InternalOptions options, NamingLens namingLens) {
    if ((!namingLens.hasPrefixRewritingLogic() && options.emulateLibraryInterface.isEmpty())
        || options.coreLibraryCompilation) {
      return new NopCodeToKeep();
    }
    return new DesugaredLibraryCodeToKeep(namingLens, options);
  }

  abstract void recordMethod(DexMethod method);

  abstract void recordField(DexField field);

  abstract void recordClass(DexType type);

  abstract boolean isNop();

  abstract void generateKeepRules(InternalOptions options);

  public static class DesugaredLibraryCodeToKeep extends CodeToKeep {

    private final NamingLens namingLens;
    private final Set<DexType> emulatedInterfaces = Sets.newIdentityHashSet();
    private final Map<DexType, Pair<Set<DexField>, Set<DexMethod>>> toKeep =
        new ConcurrentHashMap<>();

    public DesugaredLibraryCodeToKeep(NamingLens namingLens, InternalOptions options) {
      // Any class implementing one interface should implement the other one.
      // Interface method desugaring should have created the types if emulatedLibraryInterfaces
      // are set.
      for (String rewrittenName : options.emulateLibraryInterface.values()) {
        emulatedInterfaces.add(
            options.itemFactory.lookupType(
                options.itemFactory.lookupString(
                    DescriptorUtils.javaTypeToDescriptor(rewrittenName))));
      }
      this.namingLens = namingLens;
    }

    private boolean shouldKeep(DexType type) {
      return namingLens.prefixRewrittenType(type) != null || emulatedInterfaces.contains(type);
    }

    @Override
    void recordMethod(DexMethod method) {
      if (shouldKeep(method.holder)) {
        keepClass(method.holder);
        toKeep.get(method.holder).getSecond().add(method);
      }
      if (shouldKeep(method.proto.returnType)) {
        keepClass(method.proto.returnType);
      }
      for (DexType type : method.proto.parameters.values) {
        if (shouldKeep(type)) {
          keepClass(type);
        }
      }
    }

    @Override
    void recordField(DexField field) {
      if (shouldKeep(field.holder)) {
        keepClass(field.holder);
        toKeep.get(field.holder).getFirst().add(field);
      }
      if (shouldKeep(field.type)) {
        keepClass(field.type);
      }
    }

    @Override
    void recordClass(DexType type) {
      if (shouldKeep(type)) {
        keepClass(type);
      }
    }

    private void keepClass(DexType type) {
      toKeep.putIfAbsent(
          type, new Pair<>(Sets.newConcurrentHashSet(), Sets.newConcurrentHashSet()));
    }

    @Override
    boolean isNop() {
      return false;
    }

    private String convertType(DexType type) {
      DexString rewriteType = namingLens.prefixRewrittenType(type);
      DexString descriptor = rewriteType != null ? rewriteType : type.descriptor;
      return DescriptorUtils.descriptorToJavaType(descriptor.toString());
    }

    @Override
    void generateKeepRules(InternalOptions options) {
      // TODO(b/134734081): Stream the consumer instead of building the String.
      StringBuilder sb = new StringBuilder();
      String cr = System.lineSeparator();
      for (DexType type : toKeep.keySet()) {
        Set<DexField> fieldsToKeep = toKeep.get(type).getFirst();
        Set<DexMethod> methodsToKeep = toKeep.get(type).getSecond();
        sb.append("-keep class ").append(convertType(type));
        if (fieldsToKeep.isEmpty() && methodsToKeep.isEmpty()) {
          sb.append(cr);
          continue;
        }
        sb.append(" {").append(cr);
        for (DexField field : fieldsToKeep) {
          sb.append("    ")
              .append(convertType(type))
              .append(" ")
              .append(field.name)
              .append(";")
              .append(cr);
        }
        for (DexMethod method : methodsToKeep) {
          sb.append("    ")
              .append(convertType(method.proto.returnType))
              .append(" ")
              .append(method.name)
              .append("(");
          for (int i = 0; i < method.getArity(); i++) {
            if (i != 0) {
              sb.append(", ");
            }
            sb.append(convertType(method.proto.parameters.values[i]));
          }
          sb.append(");").append(cr);
        }
        sb.append("}").append(cr);
      }
      options.testing.desugaredLibraryKeepRuleConsumer.accept(sb.toString(), options.reporter);
    }
  }

  public static class NopCodeToKeep extends CodeToKeep {

    @Override
    void recordMethod(DexMethod method) {}

    @Override
    void recordField(DexField field) {}

    @Override
    void recordClass(DexType type) {}

    @Override
    boolean isNop() {
      return true;
    }

    @Override
    void generateKeepRules(InternalOptions options) {
      throw new Unreachable("Has no keep rules to generate");
    }
  }
}
