// 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.graph;

import static com.android.tools.r8.utils.StringUtils.LINE_SEPARATOR;

import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.contexts.CompilationContext;
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.conversion.OneTimeMethodProcessor;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackIgnore;
import com.android.tools.r8.kotlin.Kotlin;
import com.android.tools.r8.kotlin.KotlinMetadataWriter;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.MemberNaming.FieldSignature;
import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
import com.android.tools.r8.utils.CfgPrinter;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import java.io.BufferedReader;
import java.io.PrintStream;
import java.io.StringReader;
import java.util.stream.Collectors;

public class AssemblyWriter extends DexByteCodeWriter {

  private final boolean writeAllClassInfo;
  private final boolean writeFields;
  private final boolean writeAnnotations;
  private final boolean writeIR;
  private final boolean writeCode;
  private final AppInfo appInfo;
  private final Kotlin kotlin;
  private final Timing timing = new Timing("AssemblyWriter");
  private final CompilationContext compilationContext;

  public AssemblyWriter(
      DexApplication application,
      InternalOptions options,
      boolean allInfo,
      boolean writeIR,
      boolean writeCode) {
    super(application, options);
    this.compilationContext = CompilationContext.createInitialContext(options);
    this.writeAllClassInfo = allInfo;
    this.writeFields = allInfo;
    this.writeAnnotations = allInfo;
    this.writeIR = writeIR;
    this.writeCode = writeCode;
    if (writeIR) {
      this.appInfo =
          AppInfo.createInitialAppInfo(
              application.toDirect(), GlobalSyntheticsStrategy.forNonSynthesizing());
      if (options.programConsumer == null) {
        // Use class-file backend, since the CF frontend for testing does not support desugaring of
        // synchronized methods for the DEX backend (b/109789541).
        options.programConsumer = ClassFileConsumer.emptyConsumer();
      }
      options.outline.enabled = false;
    } else {
      this.appInfo = null;
    }
    kotlin = new Kotlin(application.dexItemFactory);
  }

  public static String getFileEnding() {
    return ".dump";
  }

  @Override
  void writeClassHeader(DexProgramClass clazz, PrintStream ps) {
    String clazzName;
    if (application.getProguardMap() != null) {
      clazzName = application.getProguardMap().originalNameOf(clazz.type);
    } else {
      clazzName = clazz.type.toSourceString();
    }
    ps.println("# Bytecode for");
    ps.println("# Class: '" + clazzName + "'");
    if (writeAllClassInfo) {
      writeAnnotations(clazz, clazz.annotations(), ps);
      ps.println("# Flags: '" + clazz.accessFlags + "'");
      if (clazz.superType != application.dexItemFactory.objectType) {
        ps.println("# Extends: '" + clazz.superType.toSourceString() + "'");
      }
      for (DexType value : clazz.interfaces.values) {
        ps.println("# Implements: '" + value.toSourceString() + "'");
      }
      if (!clazz.getInnerClasses().isEmpty()) {
        ps.println("# InnerClasses:");
        for (InnerClassAttribute innerClassAttribute : clazz.getInnerClasses()) {
          ps.println(
              "#  Outer: "
                  + (innerClassAttribute.getOuter() != null
                      ? innerClassAttribute.getOuter().toSourceString()
                      : "-")
                  + ", inner: "
                  + innerClassAttribute.getInner().toSourceString()
                  + ", inner name: "
                  + innerClassAttribute.getInnerName()
                  + ", access: "
                  + Integer.toHexString(innerClassAttribute.getAccess()));
        }
      }
      EnclosingMethodAttribute enclosingMethodAttribute = clazz.getEnclosingMethodAttribute();
      if (enclosingMethodAttribute != null) {
        ps.println("# EnclosingMethod:");
        if (enclosingMethodAttribute.getEnclosingClass() != null) {
          ps.println("#  Class: " + enclosingMethodAttribute.getEnclosingClass().toSourceString());
        } else {
          ps.println(
              "#  Method: " + enclosingMethodAttribute.getEnclosingMethod().toSourceString());
        }
      }
    }
    ps.println();
  }

  @Override
  void writeFieldsHeader(DexProgramClass clazz, PrintStream ps) {
    if (writeFields) {
      ps.println("#");
      ps.println("# Fields:");
      ps.println("#");
    }
  }

  @Override
  void writeField(DexEncodedField field, PrintStream ps) {
    if (writeFields) {
      ClassNameMapper naming = application.getProguardMap();
      FieldSignature fieldSignature =
          naming != null
              ? naming.originalSignatureOf(field.getReference())
              : FieldSignature.fromDexField(field.getReference());
      writeAnnotations(null, field.annotations(), ps);
      ps.print(field.accessFlags + " ");
      ps.print(fieldSignature);
      if (field.isStatic() && field.hasExplicitStaticValue()) {
        ps.print(" = " + field.getStaticValue());
      }
      ps.println();
    }
  }

  @Override
  void writeFieldsFooter(DexProgramClass clazz, PrintStream ps) {
    ps.println();
  }

  @Override
  void writeMethod(ProgramMethod method, PrintStream ps) {
    DexEncodedMethod definition = method.getDefinition();
    ClassNameMapper naming = application.getProguardMap();
    String methodName =
        naming != null
            ? naming.originalSignatureOf(method.getReference()).name
            : method.getReference().name.toString();
    ps.println("#");
    ps.println("# Method: '" + methodName + "':");
    writeAnnotations(null, definition.annotations(), ps);
    ps.println("# " + definition.accessFlags);
    ps.println("#");
    ps.println();
    if (!writeCode) {
      return;
    }
    Code code = definition.getCode();
    if (code != null) {
      if (writeIR) {
        writeIR(method, ps);
      } else {
        ps.println(code.toString(definition, naming));
      }
    }
  }

  private void writeIR(ProgramMethod method, PrintStream ps) {
    CfgPrinter printer = new CfgPrinter();
    IRConverter converter = new IRConverter(appInfo, timing, printer);
    OneTimeMethodProcessor methodProcessor =
        OneTimeMethodProcessor.create(method, compilationContext.createProcessorContext());
    methodProcessor.forEachWaveWithExtension(
        (ignore, methodProcessingContext) ->
            converter.processDesugaredMethod(
                method,
                OptimizationFeedbackIgnore.getInstance(),
                methodProcessor,
                methodProcessingContext));
    ps.println(printer.toString());
  }

  private void writeAnnotations(
      DexProgramClass clazz, DexAnnotationSet annotations, PrintStream ps) {
    if (writeAnnotations) {
      if (!annotations.isEmpty()) {
        ps.println("# Annotations:");
        String prefix = "#  ";
        for (DexAnnotation annotation : annotations.annotations) {
          if (annotation.annotation.type == kotlin.factory.kotlinMetadataType) {
            assert clazz != null : "Kotlin metadata is a class annotation";
            KotlinMetadataWriter.writeKotlinMetadataAnnotation(prefix, annotation, ps, kotlin);
          } else {
            String annotationString = annotation.toString();
            ps.print(
                new BufferedReader(new StringReader(annotationString))
                    .lines()
                    .collect(
                        Collectors.joining(
                            LINE_SEPARATOR + prefix + "  ", prefix, LINE_SEPARATOR)));
          }
        }
      }
    }
  }

  @Override
  void writeClassFooter(DexProgramClass clazz, PrintStream ps) {

  }
}
