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

import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.PackageReference;
import com.android.tools.r8.references.TypeReference;
import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedClass;
import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedField;
import com.android.tools.r8.tracereferences.TraceReferencesConsumer.TracedMethod;
import com.android.tools.r8.tracereferences.internal.TraceReferencesResult;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.StringUtils.BraceType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

abstract class Formatter {

  private final StringBuilder output;

  Formatter() {
    output = new StringBuilder();
  }

  String get() {
    return output.toString();
  }

  protected void append(String string) {
    output.append(string);
  }

  protected void appendLine(String string) {
    output.append(StringUtils.lines(string));
  }

  protected void printArguments(MethodReference method) {
    StringUtils.append(
        output,
        ListUtils.map(method.getFormalTypes(), TypeReference::getTypeName),
        ",",
        BraceType.PARENS);
  }

  protected abstract void printConstructorName(MethodReference method);

  protected abstract void printField(TracedField field);

  protected abstract void printMethod(TracedMethod method);

  protected abstract void printPackageNames(List<String> packageNames);

  protected void printReturn(MethodReference method) {
    append(method.getReturnType() != null ? method.getReturnType().getTypeName() : "void");
  }

  protected void printNameAndReturn(MethodReference method) {
    if (method.getMethodName().equals("<init>")) {
      printConstructorName(method);
    } else {
      printReturn(method);
      append(" ");
      append(method.getMethodName());
    }
  }

  protected abstract void printTypeHeader(TracedClass clazz);

  protected abstract void printTypeFooter();

  void format(TraceReferencesResult result) {
    print(
        result.getTracedClasses(),
        result.getTracedPackageNames(),
        result.getTracedFields(),
        result.getTracedMethods());
  }

  private void print(
      Set<TracedClass> types,
      Set<PackageReference> keepPackageNames,
      Map<ClassReference, Set<TracedField>> fields,
      Map<ClassReference, Set<TracedMethod>> methods) {
    List<TracedClass> sortedTypes = new ArrayList<>(types);
    sortedTypes.sort(Comparator.comparing(tracedClass -> tracedClass.getReference().getTypeName()));
    for (TracedClass type : sortedTypes) {
      Set<TracedMethod> methodsForClass =
          methods.getOrDefault(type.getReference(), Collections.emptySet());
      Set<TracedField> fieldsForClass =
          fields.getOrDefault(type.getReference(), Collections.emptySet());
      if (type.isMissingDefinition()) {
        continue;
      }
      printTypeHeader(type);
      List<TracedMethod> sortedMethods = new ArrayList<>(methodsForClass.size());
      for (TracedMethod method : methodsForClass) {
        if (method.isMissingDefinition()) {
          continue;
        }
        assert method.getAccessFlags() != null;
        sortedMethods.add(method);
      }
      sortedMethods.sort(
          Comparator.comparing(tracedMethod -> tracedMethod.getReference().toString()));
      for (TracedMethod method : sortedMethods) {
        printMethod(method);
      }
      List<TracedField> sortedFields = new ArrayList<>(fieldsForClass);
      sortedFields.sort(Comparator.comparing(tracedField -> tracedField.getReference().toString()));
      for (TracedField field : sortedFields) {
        if (field.isMissingDefinition()) {
          continue;
        }
        printField(field);
      }
      printTypeFooter();
    }
    List<String> packageNamesToKeep =
        keepPackageNames.stream()
            .map(PackageReference::getPackageName)
            .sorted()
            .collect(Collectors.toList());
    printPackageNames(packageNamesToKeep);
  }
}
