// Copyright (c) 2018, 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.utils;

import com.android.tools.r8.ArchiveClassFileProvider;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.Keep;
import com.android.tools.r8.dexsplitter.DexSplitter.FeatureJar;
import com.android.tools.r8.origin.PathOrigin;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * Provides a mappings of classes to modules. The structure of the input file is as follows:
 * packageOrClass:module
 *
 * <p>Lines with a # prefix are ignored.
 *
 * <p>We will do most specific matching, i.e.,
 * <pre>
 *   com.google.foobar.*:feature2
 *   com.google.*:base
 * </pre>
 * will put everything in the com.google namespace into base, except classes in com.google.foobar
 * that will go to feature2. Class based mappings takes precedence over packages (since they are
 * more specific):
 * <pre>
 *   com.google.A:feature2
 *   com.google.*:base
 *  </pre>
 * Puts A into feature2, and all other classes from com.google into base.
 *
 * <p>Note that this format does not allow specifying inter-module dependencies, this is simply a
 * placement tool.
 */
@Keep
public final class FeatureClassMapping {

  HashMap<String, String> parsedRules = new HashMap<>(); // Already parsed rules.
  HashMap<String, String> parseNonClassRules = new HashMap<>();
  boolean usesOnlyExactMappings = true;

  HashSet<FeaturePredicate> mappings = new HashSet<>();

  Path mappingFile;
  String baseName = DEFAULT_BASE_NAME;

  static final String DEFAULT_BASE_NAME = "base";

  static final String COMMENT = "#";
  static final String SEPARATOR = ":";

  public String getBaseName() {
    return baseName;
  }

  private static class SpecificationOrigin extends PathOrigin {

    public SpecificationOrigin(Path path) {
      super(path);
    }

    @Override
    public String part() {
      return "specification file '" + super.part() + "'";
    }
  }

  private static class JarFileOrigin extends PathOrigin {

    public JarFileOrigin(Path path) {
      super(path);
    }

    @Override
    public String part() {
      return "jar file '" + super.part() + "'";
    }
  }

  public static FeatureClassMapping fromSpecification(Path file) throws FeatureMappingException {
    return fromSpecification(file, new DiagnosticsHandler() {});
  }

  public static FeatureClassMapping fromSpecification(Path file, DiagnosticsHandler reporter)
      throws FeatureMappingException {
    FeatureClassMapping mapping = new FeatureClassMapping();
    List<String> lines = null;
    try {
      lines = FileUtils.readAllLines(file);
    } catch (IOException e) {
      reporter.error(new ExceptionDiagnostic(e, new SpecificationOrigin(file)));
      throw new AbortException();
    }
    for (int i = 0; i < lines.size(); i++) {
      String line = lines.get(i);
      mapping.parseAndAdd(line, i);
    }
    return mapping;
  }

  public static class Internal {
    private static List<String> getClassFileDescriptors(String jar, DiagnosticsHandler reporter) {
      Path jarPath = Paths.get(jar);
      try {
        return new ArchiveClassFileProvider(jarPath).getClassDescriptors()
            .stream()
            .map(DescriptorUtils::descriptorToJavaType)
            .collect(Collectors.toList());
      } catch (IOException e) {
        reporter.error(new ExceptionDiagnostic(e, new JarFileOrigin(jarPath)));
        throw new AbortException();
      }
    }

    private static List<String> getNonClassFiles(String jar, DiagnosticsHandler reporter) {
      try (ZipFile zipfile = new ZipFile(jar, StandardCharsets.UTF_8)) {
          return zipfile.stream()
              .filter(entry -> !ZipUtils.isClassFile(entry.getName()))
              .map(ZipEntry::getName)
              .collect(Collectors.toList());
        } catch (IOException e) {
          reporter.error(new ExceptionDiagnostic(e, new JarFileOrigin(Paths.get(jar))));
          throw new AbortException();
        }
    }

    public static FeatureClassMapping fromJarFiles(
        List<FeatureJar> featureJars, List<String> baseJars, String baseName,
        DiagnosticsHandler reporter)
        throws FeatureMappingException {
      FeatureClassMapping mapping = new FeatureClassMapping();
      if (baseName != null) {
        mapping.baseName = baseName;
      }
      for (FeatureJar featureJar : featureJars) {
        for (String javaType : getClassFileDescriptors(featureJar.getJar(), reporter)) {
          mapping.addMapping(javaType, featureJar.getOutputName());
        }
        for (String nonClass : getNonClassFiles(featureJar.getJar(), reporter)) {
          mapping.addNonClassMapping(nonClass, featureJar.getOutputName());
        }
      }
      for (String baseJar : baseJars) {
        for (String javaType : getClassFileDescriptors(baseJar, reporter)) {
          mapping.addBaseMapping(javaType);
        }
        for (String nonClass : getNonClassFiles(baseJar, reporter)) {
          mapping.addBaseNonClassMapping(nonClass);
        }
      }
      assert mapping.usesOnlyExactMappings;
      return mapping;
    }

  }

  private FeatureClassMapping() {}

  public void addBaseMapping(String clazz) throws FeatureMappingException {
    addMapping(clazz, baseName);
  }

  public void addBaseNonClassMapping(String name) {
    addNonClassMapping(name, baseName);
  }

  public void addMapping(String clazz, String feature) throws FeatureMappingException {
    addRule(clazz, feature, 0);
  }

  public void addNonClassMapping(String name, String feature) {
    // If a non-class file is present in multiple features put the resource in the base.
    parseNonClassRules.put(name, parseNonClassRules.containsKey(name) ? baseName : feature);
  }

  FeatureClassMapping(List<String> lines) throws FeatureMappingException {
    for (int i = 0; i < lines.size(); i++) {
      String line = lines.get(i);
      parseAndAdd(line, i);
    }
  }

  public String featureForClass(String clazz) {
    if (usesOnlyExactMappings) {
      return parsedRules.getOrDefault(clazz, baseName);
    } else {
      FeaturePredicate bestMatch = null;
      for (FeaturePredicate mapping : mappings) {
        if (mapping.match(clazz)) {
          if (bestMatch == null || bestMatch.predicate.length() < mapping.predicate.length()) {
            bestMatch = mapping;
          }
        }
      }
      if (bestMatch == null) {
        return baseName;
      }
      return bestMatch.feature;
    }
  }

  public String featureForNonClass(String nonClass) {
    return parseNonClassRules.getOrDefault(nonClass, baseName);
  }

  private void parseAndAdd(String line, int lineNumber) throws FeatureMappingException {
    if (line.startsWith(COMMENT)) {
      return; // Ignore comments
    }
    if (line.isEmpty()) {
      return; // Ignore blank lines
    }

    if (!line.contains(SEPARATOR)) {
      error("Mapping lines must contain a " + SEPARATOR, lineNumber);
    }
    String[] values = line.split(SEPARATOR);
    if (values.length != 2) {
      error("Mapping lines can only contain one " + SEPARATOR, lineNumber);
    }

    String predicate = values[0];
    String feature = values[1];
    addRule(predicate, feature, lineNumber);
  }

  private void addRule(String predicate, String feature, int lineNumber)
      throws FeatureMappingException {
    if (parsedRules.containsKey(predicate)) {
      if (!parsedRules.get(predicate).equals(feature)) {
        error("Redefinition of predicate " + predicate + "not allowed", lineNumber);
      }
      return; // Already have this rule.
    }
    parsedRules.put(predicate, feature);
    FeaturePredicate featurePredicate = new FeaturePredicate(predicate, feature);
    mappings.add(featurePredicate);
    usesOnlyExactMappings &= featurePredicate.isExactmapping();
  }

  private void error(String error, int line) throws FeatureMappingException {
    throw new FeatureMappingException(
        "Invalid mappings specification: " + error + "\n in file " + mappingFile + ":" + line);
  }

  @Keep
  public static class FeatureMappingException extends Exception {
    FeatureMappingException(String message) {
      super(message);
    }
  }

  /** A feature predicate can either be a wildcard or class predicate. */
  private static class FeaturePredicate {
    private static Pattern identifier = Pattern.compile("[A-Za-z_\\-][A-Za-z0-9_$\\-]*");
    final String predicate;
    final String feature;
    final boolean isCatchAll;
    // False implies class predicate.
    final boolean isWildcard;

    FeaturePredicate(String predicate, String feature) throws FeatureMappingException {
      isWildcard = predicate.endsWith(".*");
      isCatchAll =  predicate.equals("*");
      if (isCatchAll) {
        this.predicate = "";
      } else if (isWildcard) {
        String packageName = predicate.substring(0, predicate.length() - 2);
        if (!DescriptorUtils.isValidJavaType(packageName)) {
          throw new FeatureMappingException(packageName + " is not a valid identifier");
        }
        // Prefix of a fully-qualified class name, including a terminating dot.
        this.predicate = predicate.substring(0, predicate.length() - 1);
      } else {
        if (!DescriptorUtils.isValidJavaType(predicate)) {
          throw new FeatureMappingException(predicate + " is not a valid identifier");
        }
        this.predicate = predicate;
      }
      this.feature = feature;
    }

    boolean match(String className) {
      if (isCatchAll) {
        return true;
      } else if (isWildcard) {
        return className.startsWith(predicate);
      } else {
        return className.equals(predicate);
      }
    }

    boolean isExactmapping() {
      return !isWildcard && !isCatchAll;
    }
  }
}
