// 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 com.android.tools.r8.utils.StringUtils;
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(StringUtils.LINE_SEPARATOR);
  }

  // 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(':');
      writer.append(StringUtils.LINE_SEPARATOR);
      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(StringUtils.LINE_SEPARATOR);
  }

  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(StringUtils.LINE_SEPARATOR);
  }

  // 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.
    }
  }
}
