/*
 * Copyright 2014-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package com.facebook.buck.java;

import com.facebook.buck.io.ProjectFilesystem;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JavacErrorParser {

  private final ProjectFilesystem filesystem;
  private final JavaPackageFinder javaPackageFinder;

  private static ImmutableList<Pattern> onePartPatterns = ImmutableList.of(
      Pattern.compile(
          "error: cannot access (?<symbol>\\S+)"),
      Pattern.compile(
          "error: package \\S+ does not exist\nimport (?<symbol>\\S+);"),
      Pattern.compile(
          "error: package \\S+ does not exist\nimport static (?<symbol>\\S+)\\.[^.]+;"));

  private static ImmutableList<Pattern> twoPartPatterns = ImmutableList.of(
      Pattern.compile(
          "\\s*symbol:\\s+class (?<class>\\S+)\n\\s*location:\\s+package (?<package>\\S+)"));

  // These patterns match missing symbols that live in the current package.  Usually, that means one
  // java package that's split up into multiple java_library rules, which depend on each other.
  // Classes in the same package can reference symbols without an import or fully qualified name,
  // which means we have to infer the package name from the filepath in the error.
  // NOTE: Regular missing symbols in other packages will often generate compiler errors that match
  // these patterns, because imported symbols are used unqualified after the import. That means we
  // might go looking for an imported symbol in the current package (wrong) in addition to the
  // package it was imported from (right). That's ultimately fine, because the symbol can't exist in
  // both places (without causing another compiler error).
  private static ImmutableList<Pattern> localPackagePatterns = ImmutableList.of(
      Pattern.compile(
          "^(?<file>.+):[0-9]+: error: cannot find symbol\n" +
          ".*\n" +
          ".*\n" +
          "\\s*symbol:\\s+(class|variable) (?<class>\\S+)"),
      Pattern.compile(
          "^(?<file>.+):[0-9]+: error: package (?<class>\\S+) does not exist"));

  public JavacErrorParser(ProjectFilesystem filesystem, JavaPackageFinder javaPackageFinder) {
    this.filesystem = filesystem;
    this.javaPackageFinder = javaPackageFinder;
  }

  public Optional<String> getMissingSymbolFromCompilerError(String error) {
    for (Pattern pattern: onePartPatterns) {
      Matcher matcher = pattern.matcher(error);
      if (matcher.find()) {
        return Optional.of(matcher.group("symbol"));
      }
    }

    for (Pattern pattern: twoPartPatterns) {
      Matcher matcher = pattern.matcher(error);
      if (matcher.find()) {
        return Optional.of(matcher.group("package") + "." + matcher.group("class"));
      }
    }

    for (Pattern pattern: localPackagePatterns) {
      Matcher matcher = pattern.matcher(error);
      if (matcher.find()) {
        return getMissingSymbolInLocalPackage(matcher);
      }
    }

    return Optional.absent();
  }

  private Optional<String> getMissingSymbolInLocalPackage(Matcher matcher) {
    String fileName = matcher.group("file");
    String className = matcher.group("class");
    Path repoRoot = filesystem.getRootPath().toAbsolutePath().normalize();
    Path relativePath = repoRoot.relativize(Paths.get(fileName));
    String packageName = javaPackageFinder.findJavaPackageForPath(relativePath.toString());
    return Optional.of(packageName + "." + className);
  }
}
