// Copyright (c) 2022, 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.retrace.internal;

import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.LineReader;
import com.android.tools.r8.naming.MapVersion;
import com.android.tools.r8.naming.ProguardMapSupplier.ProguardMapChecker;
import com.android.tools.r8.naming.ProguardMapSupplier.ProguardMapChecker.VerifyMappingFileHashResult;
import com.android.tools.r8.naming.mappinginformation.MapVersionMappingInformation;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.retrace.InvalidMappingFileException;
import com.android.tools.r8.retrace.ProguardMapProducer;
import com.android.tools.r8.retrace.ProguardMappingSupplier;
import com.android.tools.r8.retrace.internal.ProguardMapReaderWithFiltering.ProguardMapReaderWithFilteringInputBuffer;
import com.android.tools.r8.retrace.internal.ProguardMapReaderWithFiltering.ProguardMapReaderWithFilteringMappedBuffer;
import com.android.tools.r8.utils.ExceptionDiagnostic;
import com.android.tools.r8.utils.StringDiagnostic;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

/**
 * IntelliJ highlights the class as being invalid because it cannot see getClassNameMapper is
 * defined on the class for some reason.
 */
public class ProguardMappingSupplierImpl extends ProguardMappingSupplier {

  private ProguardMapProducer proguardMapProducer;
  private final boolean allowExperimental;
  private final boolean loadAllDefinitions;

  private ClassNameMapper classNameMapper;
  private final Set<String> pendingClassMappings = new HashSet<>();
  private final Set<String> builtClassMappings = new HashSet<>();

  public ProguardMappingSupplierImpl(ClassNameMapper classNameMapper) {
    this.classNameMapper = classNameMapper;
    this.proguardMapProducer = null;
    this.allowExperimental = true;
    this.loadAllDefinitions = true;
  }

  ProguardMappingSupplierImpl(
      ProguardMapProducer proguardMapProducer,
      boolean allowExperimental,
      boolean loadAllDefinitions) {
    this.proguardMapProducer = proguardMapProducer;
    this.allowExperimental = allowExperimental;
    this.loadAllDefinitions = loadAllDefinitions;
  }

  private boolean hasClassMappingFor(String typeName) {
    return loadAllDefinitions || builtClassMappings.contains(typeName);
  }

  @Override
  public ProguardMappingSupplier registerClassUse(
      DiagnosticsHandler diagnosticsHandler, ClassReference classReference) {
    if (!hasClassMappingFor(classReference.getTypeName())) {
      pendingClassMappings.add(classReference.getTypeName());
    }
    return this;
  }

  @Override
  public void verifyMappingFileHash(DiagnosticsHandler diagnosticsHandler) {
    try (InputStream reader = proguardMapProducer.get()) {
      VerifyMappingFileHashResult checkResult =
          ProguardMapChecker.validateProguardMapHash(
              CharStreams.toString(new InputStreamReader(reader, StandardCharsets.UTF_8)));
      if (checkResult.isError()) {
        diagnosticsHandler.error(new StringDiagnostic(checkResult.getMessage()));
        throw new RuntimeException(checkResult.getMessage());
      }
      if (!checkResult.isOk()) {
        diagnosticsHandler.warning(new StringDiagnostic(checkResult.getMessage()));
      }
    } catch (IOException e) {
      diagnosticsHandler.error(new ExceptionDiagnostic(e));
      throw new RuntimeException(e);
    }
  }

  @Override
  public Set<MapVersionMappingInformation> getMapVersions(DiagnosticsHandler diagnosticsHandler) {
    if (classNameMapper == null) {
      createRetracer(diagnosticsHandler);
    }
    assert classNameMapper != null;
    return classNameMapper.getMapVersions();
  }

  @Override
  public RetracerImpl createRetracer(DiagnosticsHandler diagnosticsHandler) {
    if (proguardMapProducer == null) {
      assert classNameMapper != null;
      return RetracerImpl.createInternal(
          MappingSupplierInternalImpl.createInternal(classNameMapper), diagnosticsHandler);
    }
    if (classNameMapper == null || !pendingClassMappings.isEmpty()) {
      try {
        Predicate<String> buildForClass =
            loadAllDefinitions ? null : pendingClassMappings::contains;
        boolean readPreambleAndSourceFile = classNameMapper == null;
        LineReader reader =
            proguardMapProducer.isFileBacked()
                ? new ProguardMapReaderWithFilteringMappedBuffer(
                    proguardMapProducer.getPath(), buildForClass, readPreambleAndSourceFile)
                : new ProguardMapReaderWithFilteringInputBuffer(
                    proguardMapProducer.get(), buildForClass, readPreambleAndSourceFile);
        classNameMapper =
            ClassNameMapper.mapperFromLineReaderWithFiltering(
                    reader, getMapVersion(), diagnosticsHandler, true, allowExperimental)
                .combine(classNameMapper);
        builtClassMappings.addAll(pendingClassMappings);
        pendingClassMappings.clear();
      } catch (Exception e) {
        throw new InvalidMappingFileException(e);
      }
    }
    if (loadAllDefinitions) {
      proguardMapProducer = null;
    }
    return RetracerImpl.createInternal(
        MappingSupplierInternalImpl.createInternal(classNameMapper), diagnosticsHandler);
  }

  private MapVersion getMapVersion() {
    if (classNameMapper == null) {
      return MapVersion.MAP_VERSION_NONE;
    } else {
      MapVersionMappingInformation mapVersion = classNameMapper.getFirstMapVersionInformation();
      return mapVersion == null ? MapVersion.MAP_VERSION_UNKNOWN : mapVersion.getMapVersion();
    }
  }
}
