// 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.DiagnosticsHandler;
import com.android.tools.r8.MapIdEnvironment;
import com.android.tools.r8.MapIdProvider;
import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.Version;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.naming.mappinginformation.MapVersionMappingInformation;
import com.android.tools.r8.utils.ChainableStringConsumer;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.VersionProperties;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

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 final String MARKER_KEY_PG_MAP_HASH = "pg_map_hash";
  public static final String SHA_256_KEY = "SHA-256";

  public static int PG_MAP_ID_LENGTH = 7;

  // Hash of the Proguard map (excluding the header up to and including the hash marker).
  public static class ProguardMapId {
    private final String id;
    private final String hash;

    private ProguardMapId(String id, String hash) {
      assert id != null;
      assert hash != null;
      this.id = id;
      this.hash = hash;
    }

    /** Id for the map file (user defined or a truncated prefix of the content hash). */
    public String getId() {
      return id;
    }

    /** The actual content hash. */
    public String getHash() {
      return hash;
    }
  }

  private final ClassNameMapper classNameMapper;
  private final StringConsumer consumer;
  private final InternalOptions options;
  private final Reporter reporter;

  private ProguardMapSupplier(ClassNameMapper classNameMapper, InternalOptions options) {
    assert classNameMapper != null;
    this.classNameMapper = classNameMapper.sorted();
    // TODO(b/217111432): Validate Proguard using ProguardMapChecker without building the entire
    //  Proguard map in memory.
    this.consumer = options.proguardMapConsumer;
    this.options = options;
    this.reporter = options.reporter;
  }

  public static ProguardMapSupplier create(
      ClassNameMapper classNameMapper, InternalOptions options) {
    return new ProguardMapSupplier(classNameMapper, options);
  }

  public ProguardMapId writeProguardMap() {
    ProguardMapId id = computeProguardMapId();
    writeMarker(id);
    writeBody();
    ExceptionUtils.withFinishedResourceHandler(reporter, consumer);
    return id;
  }

  private ProguardMapId computeProguardMapId() {
    ProguardMapIdBuilder builder = new ProguardMapIdBuilder();
    classNameMapper.write(builder);
    return builder.build(options.mapIdProvider);
  }

  private void writeBody() {
    classNameMapper.write(new ProguardMapWriter());
  }

  private void writeMarker(ProguardMapId id) {
    StringBuilder builder = new StringBuilder();
    builder.append(
        "# "
            + MARKER_KEY_COMPILER
            + ": "
            + MARKER_VALUE_COMPILER
            + "\n"
            + "# "
            + MARKER_KEY_COMPILER_VERSION
            + ": "
            + Version.LABEL
            + "\n");
    if (options.isGeneratingDex()) {
      builder.append("# " + MARKER_KEY_MIN_API + ": " + options.getMinApiLevel().getLevel() + "\n");
    }
    if (Version.isDevelopmentVersion()) {
      builder.append(
          "# " + MARKER_KEY_COMPILER_HASH + ": " + VersionProperties.INSTANCE.getSha() + "\n");
    }
    // Turn off linting of the mapping file in some build systems.
    builder.append("# common_typos_disable" + "\n");
    // Emit the R8 specific map-file version.
    MapVersion mapVersion = options.getMapFileVersion();
    if (mapVersion.isGreaterThan(MapVersion.MAP_VERSION_NONE)) {
      builder
          .append("# ")
          .append(new MapVersionMappingInformation(mapVersion, mapVersion.getName()).serialize())
          .append("\n");
    }
    builder.append("# " + MARKER_KEY_PG_MAP_ID + ": " + id.getId() + "\n");
    // Place the map hash as the last header item. Everything past this line is the hashed content.
    builder
        .append("# ")
        .append(MARKER_KEY_PG_MAP_HASH)
        .append(": ")
        .append(SHA_256_KEY)
        .append(" ")
        .append(id.getHash())
        .append("\n");
    consumer.accept(builder.toString(), reporter);
  }

  static class ProguardMapIdBuilder implements ChainableStringConsumer {

    private final Hasher hasher = Hashing.sha256().newHasher();

    private MapIdProvider getProviderOrDefault(MapIdProvider provider) {
      return provider != null
          ? provider
          : environment -> environment.getMapHash().substring(0, PG_MAP_ID_LENGTH);
    }

    private MapIdEnvironment getEnvironment(String hash) {
      return new MapIdEnvironment() {
        @Override
        public String getMapHash() {
          return hash;
        }
      };
    }

    @Override
    public ProguardMapIdBuilder accept(String string) {
      hasher.putString(string, StandardCharsets.UTF_8);
      return this;
    }

    public ProguardMapId build(MapIdProvider mapIdProvider) {
      String hash = hasher.hash().toString();
      String id = getProviderOrDefault(mapIdProvider).get(getEnvironment(hash));
      return new ProguardMapId(id, hash);
    }
  }

  class ProguardMapWriter implements ChainableStringConsumer {

    @Override
    public ProguardMapWriter accept(String string) {
      consumer.accept(string, reporter);
      return this;
    }
  }

  public static class ProguardMapChecker implements StringConsumer {

    private final StringConsumer inner;
    private final StringBuilder contents = new StringBuilder();

    ProguardMapChecker(StringConsumer inner) {
      if (!InternalOptions.assertionsEnabled()) {
        // Make sure we never get here without assertions enabled.
        throw new Unreachable();
      }
      this.inner = inner;
    }

    @Override
    public void accept(String string, DiagnosticsHandler handler) {
      inner.accept(string, handler);
      contents.append(string);
    }

    @Override
    public void finished(DiagnosticsHandler handler) {
      inner.finished(handler);
      String stringContent = contents.toString();
      assert validateProguardMapParses(stringContent);
      assert validateProguardMapHash(stringContent).isOk();
    }

    private static boolean validateProguardMapParses(String content) {
      try {
        ClassNameMapper.mapperFromString(content);
      } catch (IOException e) {
        e.printStackTrace();
        return false;
      }
      return true;
    }

    public static class VerifyMappingFileHashResult {
      private final boolean error;
      private final String message;

      public static VerifyMappingFileHashResult createOk() {
        return new VerifyMappingFileHashResult(false, null);
      }

      public static VerifyMappingFileHashResult createInfo(String message) {
        return new VerifyMappingFileHashResult(false, message);
      }

      public static VerifyMappingFileHashResult createError(String message) {
        return new VerifyMappingFileHashResult(true, message);
      }

      private VerifyMappingFileHashResult(boolean error, String message) {
        this.error = error;
        this.message = message;
      }

      public boolean isOk() {
        return !error && message == null;
      }

      public boolean isError() {
        return error;
      }

      public String getMessage() {
        assert message != null;
        return message;
      }
    }

    public static VerifyMappingFileHashResult validateProguardMapHash(String content) {
      int lineEnd = -1;
      while (true) {
        int lineStart = lineEnd + 1;
        lineEnd = content.indexOf('\n', lineStart);
        if (lineEnd < 0) {
          return VerifyMappingFileHashResult.createInfo("Failure to find map hash");
        }
        String line = content.substring(lineStart, lineEnd).trim();
        if (line.isEmpty()) {
          // Ignore empty lines in the header.
          continue;
        }
        if (line.charAt(0) != '#') {
          // At the first non-empty non-comment line we assume that the file has no hash marker.
          return VerifyMappingFileHashResult.createInfo("Failure to find map hash in header");
        }
        String headerLine = line.substring(1).trim();
        if (headerLine.startsWith(MARKER_KEY_PG_MAP_HASH)) {
          int shaIndex = headerLine.indexOf(SHA_256_KEY + " ", MARKER_KEY_PG_MAP_HASH.length());
          if (shaIndex < 0) {
            return VerifyMappingFileHashResult.createError(
                "Unknown map hash function: '" + headerLine + "'");
          }
          String headerHash = headerLine.substring(shaIndex + SHA_256_KEY.length()).trim();
          // We are on the hash line. Everything past this line is the hashed content.
          Hasher hasher = Hashing.sha256().newHasher();
          String hashedContent = content.substring(lineEnd + 1);
          hasher.putString(hashedContent, StandardCharsets.UTF_8);
          String computedHash = hasher.hash().toString();
          return headerHash.equals(computedHash)
              ? VerifyMappingFileHashResult.createOk()
              : VerifyMappingFileHashResult.createError(
                  "Mismatching map hash: '" + headerHash + "' != '" + computedHash + "'");
        }
      }
    }
  }
}
