// 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.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
import java.nio.charset.StandardCharsets;

class UsagePrinter {
  private static final String INDENT = "    ";

  static final UsagePrinter DONT_PRINT = new NoOpUsagePrinter();

  private final StringBuilder writer;
  private DexProgramClass enclosingClazz = null;
  private boolean clazzPrefixPrinted = false;

  UsagePrinter() {
    writer = new StringBuilder();
  }

  String toStringContent() {
    return writer.toString();
  }

  byte[] toByteArray() {
    return writer.toString().getBytes(StandardCharsets.UTF_8);
  }

  void printUnusedClass(DexProgramClass clazz) {
    writer.append(clazz.toSourceString());
    writer.append('\n');
  }

  // Visiting methods and fields of the given clazz.
  void visiting(DexProgramClass clazz) {
    assert enclosingClazz == null;
    enclosingClazz = clazz;
  }

  // Visited methods and fields of the top at the clazz stack.
  void visited() {
    enclosingClazz = null;
    clazzPrefixPrinted = false;
  }

  private void printClazzPrefixIfNecessary() {
    assert enclosingClazz != null;
    if (!clazzPrefixPrinted) {
      writer.append(enclosingClazz.toSourceString());
      writer.append('\n');
      clazzPrefixPrinted = true;
    }
  }

  void printUnusedMethod(DexEncodedMethod method) {
    printClazzPrefixIfNecessary();
    writer.append(INDENT);
    String accessFlags = method.accessFlags.toString();
    if (!accessFlags.isEmpty()) {
      writer.append(accessFlags).append(' ');
    }
    writer.append(method.method.proto.returnType.toSourceString()).append(' ');
    writer.append(method.method.name.toSourceString());
    writer.append('(');
    for (int i = 0; i < method.method.proto.parameters.values.length; i++) {
      if (i != 0) {
        writer.append(',');
      }
      writer.append(method.method.proto.parameters.values[i].toSourceString());
    }
    writer.append(')');
    writer.append('\n');
  }

  void printUnusedField(DexEncodedField field) {
    printClazzPrefixIfNecessary();
    writer.append(INDENT);
    String accessFlags = field.accessFlags.toString();
    if (!accessFlags.isEmpty()) {
      writer.append(accessFlags).append(' ');
    }
    writer.append(field.field.type.toSourceString()).append(" ");
    writer.append(field.field.name.toSourceString());
    writer.append('\n');
  }

  // Empty implementation to silently ignore printing dead code.
  private static class NoOpUsagePrinter extends UsagePrinter {

    @Override
    byte[] toByteArray() {
      return null;
    }

    @Override
    void printUnusedClass(DexProgramClass clazz) {
      // Intentionally left empty.
    }

    @Override
    void visiting(DexProgramClass clazz) {
      // Intentionally left empty.
    }

    @Override
    void visited() {
      // Intentionally left empty.
    }

    @Override
    void printUnusedMethod(DexEncodedMethod method) {
      // Intentionally left empty.
    }

    @Override
    void printUnusedField(DexEncodedField field) {
      // Intentionally left empty.
    }
  }
}
