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

import com.android.tools.r8.Version;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.VersionProperties;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;

public class ProguardMapSupplier {

  public static final String MARKER_KEY_COMPILER = "compiler";
  public static final String MARKER_VALUE_COMPILER = "R8";
  public static final String MARKER_KEY_COMPILER_VERSION = "compiler_version";
  public static final String MARKER_KEY_COMPILER_HASH = "compiler_hash";
  public static final String MARKER_KEY_MIN_API = "min_api";
  public static final String MARKER_KEY_PG_MAP_ID = "pg_map_id";

  public static int PG_MAP_ID_LENGTH = 7;

  public static ProguardMapSupplier fromClassNameMapper(
      ClassNameMapper classNameMapper, InternalOptions options) {
    return new ProguardMapSupplier(true, classNameMapper, null, null, options);
  }

  public static ProguardMapSupplier fromNamingLens(
      NamingLens namingLens, DexApplication dexApplication, InternalOptions options) {
    return new ProguardMapSupplier(false, null, namingLens, dexApplication, options);
  }

  public static class ProguardMapAndId {
    public final String map;
    public final String id;

    ProguardMapAndId(String map, String id) {
      assert map != null && id != null;
      this.map = map;
      this.id = id;
    }
  }

  public ProguardMapSupplier(
      boolean useClassNameMapper,
      ClassNameMapper classNameMapper,
      NamingLens namingLens,
      DexApplication application,
      InternalOptions options) {
    this.useClassNameMapper = useClassNameMapper;
    this.classNameMapper = classNameMapper;
    this.namingLens = namingLens;
    this.application = application;
    this.minApiLevel = options.isGeneratingClassFiles() ? null : options.minApiLevel;
  }

  private final boolean useClassNameMapper;
  private final ClassNameMapper classNameMapper;
  private final NamingLens namingLens;
  private final DexApplication application;
  private final Integer minApiLevel;

  public ProguardMapAndId getProguardMapAndId() {
    String body = getBody();
    if (body == null || body.trim().length() == 0) {
      return null;
    }
    // Algorithm:
    // Hash of the non-whitespace codepoints of the input string.
    Hasher hasher = Hashing.murmur3_32().newHasher();
    body.codePoints().filter(c -> !Character.isWhitespace(c)).forEach(hasher::putInt);
    String proguardMapId = hasher.hash().toString().substring(0, PG_MAP_ID_LENGTH);

    StringBuilder builder = new StringBuilder();
    builder.append(
        "# "
            + MARKER_KEY_COMPILER
            + ": "
            + MARKER_VALUE_COMPILER
            + "\n"
            + "# "
            + MARKER_KEY_COMPILER_VERSION
            + ": "
            + Version.LABEL
            + "\n");
    if (minApiLevel != null) {
      builder.append("# " + MARKER_KEY_MIN_API + ": " + minApiLevel + "\n");
    }
    if (Version.isDev()) {
      builder.append(
          "# " + MARKER_KEY_COMPILER_HASH + ": " + VersionProperties.INSTANCE.getSha() + "\n");
    }
    builder.append("# " + MARKER_KEY_PG_MAP_ID + ": " + proguardMapId + "\n");
    // Turn off linting of the mapping file in some build systems.
    builder.append("# common_typos_disable" + "\n");
    builder.append(body);

    return new ProguardMapAndId(builder.toString(), proguardMapId);
  }

  private String getBody() {
    if (useClassNameMapper) {
      assert classNameMapper != null;
      return classNameMapper.toString();
    }
    assert namingLens != null && application != null;
    // TODO(herhut): Should writing of the proguard-map file be split like this?
    if (!namingLens.isIdentityLens()) {
      StringBuilder map = new StringBuilder();
      new MinifiedNameMapPrinter(application, namingLens).write(map);
      return map.toString();
    }
    if (application.getProguardMap() != null) {
      ByteArrayOutputStream bytes = new ByteArrayOutputStream();
      Writer writer = new PrintWriter(bytes);
      try {
        application.getProguardMap().write(writer);
        writer.flush();
      } catch (IOException e) {
        throw new RuntimeException("IOException while creating Proguard-map output: " + e);
      }
      return bytes.toString();
    }
    return null;
  }
}
