/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.google.idea.blaze.base.issueparser;

import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.projectview.ProjectViewManager;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.section.ListSection;
import com.google.idea.blaze.base.projectview.section.Section;
import com.google.idea.blaze.base.projectview.section.SectionKey;
import com.google.idea.blaze.base.projectview.section.sections.TargetSection;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.google.common.base.Preconditions.checkState;

/**
 * Parses blaze output for compile errors.
 */
public class BlazeIssueParser {

  private static class ParseResult {

    public static final ParseResult NEEDS_MORE_INPUT = new ParseResult(true, null);

    public static final ParseResult NO_RESULT = new ParseResult(false, null);

    private boolean needsMoreInput;
    @Nullable private IssueOutput output;

    private ParseResult(boolean needsMoreInput, IssueOutput output) {
      this.needsMoreInput = needsMoreInput;
      this.output = output;
    }

    public static ParseResult needsMoreInput() {
      return NEEDS_MORE_INPUT;
    }

    public static ParseResult output(IssueOutput output) {
      return new ParseResult(false, output);
    }

    public static ParseResult noResult() {
      return NO_RESULT;
    }
  }

  interface Parser {
    @NotNull
    ParseResult parse(@NotNull String currentLine, @NotNull List<String> previousLines);
  }

  static abstract class SingleLineParser implements Parser {
    @NotNull
    Pattern pattern;

    SingleLineParser(@NotNull String regex) {
      pattern = Pattern.compile(regex);
    }

    @Override
    public ParseResult parse(@NotNull String currentLine, @NotNull List<String> multilineMatchResult) {
      checkState(multilineMatchResult.isEmpty(), "SingleLineParser recieved multiple lines of input");
      return parse(currentLine);
    }

    ParseResult parse(@NotNull String line) {
      Matcher matcher = pattern.matcher(line);
      if (matcher.find()) {
        return ParseResult.output(createIssue(matcher));
      }
      return ParseResult.noResult();
    }

    @Nullable
    protected abstract IssueOutput createIssue(@NotNull Matcher matcher);
  }

  static class CompileParser extends SingleLineParser {
    @NotNull
    private final WorkspaceRoot workspaceRoot;

    public CompileParser(@NotNull WorkspaceRoot workspaceRoot) {
      super("(.*?):([0-9]+):([0-9]+:)? (error|warning): (.*)");
      this.workspaceRoot = workspaceRoot;
    }

    @Override
    protected IssueOutput createIssue(@NotNull Matcher matcher) {
      final File file;
      try {
        String fileName = matcher.group(1);
        final WorkspacePath workspacePath;
        if (fileName.startsWith("//depot/google3/")) {
          workspacePath = new WorkspacePath(fileName.substring("//depot/google3/".length()));
        } else if (fileName.startsWith("/")) {
          workspacePath = workspaceRoot.workspacePathFor(new File(fileName));
        } else {
          workspacePath = new WorkspacePath(fileName);
        }
        file = workspaceRoot.fileForPath(workspacePath);
      }
      catch (IllegalArgumentException e) {
        // Ignore -- malformed error message
        return null;
      }

      IssueOutput.Category type = matcher.group(4).equals("error")
                                  ? IssueOutput.Category.ERROR
                                  : IssueOutput.Category.WARNING;
      return IssueOutput.issue(type, matcher.group(5))
        .inFile(file)
        .onLine(Integer.parseInt(matcher.group(2)))
        .build();
    }
  }

  static class TracebackParser implements Parser {
    private static final Pattern PATTERN = Pattern.compile("(ERROR): (.*?):([0-9]+):([0-9]+): (Traceback \\(most recent call last\\):)");

    @NotNull
    @Override
    public ParseResult parse(@NotNull String currentLine, @NotNull List<String> previousLines) {
      if (previousLines.isEmpty()) {
        if (PATTERN.matcher(currentLine).find()) {
          return ParseResult.needsMoreInput();
        }
        else {
          return ParseResult.noResult();
        }
      }

      if (currentLine.startsWith("\t")) {
        return ParseResult.needsMoreInput();
      }
      else {
        Matcher matcher = PATTERN.matcher(previousLines.get(0));
        checkState(matcher.find(), "Found a match in the first line previously, but now it isn't there.");
        StringBuilder message = new StringBuilder(matcher.group(5));
        for (int i = 1; i < previousLines.size(); ++i) {
          message.append(System.lineSeparator())
            .append(previousLines.get(i));
        }
        message.append(System.lineSeparator())
          .append(currentLine);
        return ParseResult.output(IssueOutput.error(message.toString())
                                    .inFile(new File(matcher.group(2)))
                                    .onLine(Integer.parseInt(matcher.group(3)))
                                    .build());
      }
    }
  }

  static class BuildParser extends SingleLineParser {
    BuildParser() {
      super("(ERROR): (.*?):([0-9]+):([0-9]+): (.*)");
    }

    @Override
    protected IssueOutput createIssue(@NotNull Matcher matcher) {
      return IssueOutput.error(matcher.group(5))
        .inFile(new File(matcher.group(2)))
        .onLine(Integer.parseInt(matcher.group(3)))
        .build();
    }
  }

  static class LinelessBuildParser extends SingleLineParser {
    LinelessBuildParser() {
      super("(ERROR): (.*?):char offsets [0-9]+--[0-9]+: (.*)");
    }

    @Override
    protected IssueOutput createIssue(@NotNull Matcher matcher) {
      return IssueOutput.error(matcher.group(3))
        .inFile(new File(matcher.group(2)))
        .build();
    }
  }

  static class ProjectViewLabelParser extends SingleLineParser {

    @Nullable private final ProjectViewSet projectViewSet;

    ProjectViewLabelParser(
      @Nullable ProjectViewSet projectViewSet) {
      super("no such target '(.*)': target .*? not declared in package .*? defined by");
      this.projectViewSet = projectViewSet;
    }

    @Override
    protected IssueOutput createIssue(@NotNull Matcher matcher) {
      File file = null;
      if (projectViewSet != null) {
        String targetString = matcher.group(1);
        final TargetExpression targetExpression = TargetExpression.fromString(targetString);
        file = projectViewFileWithSection(projectViewSet, TargetSection.KEY, new Predicate<ListSection<TargetExpression>>() {
          @Override
          public boolean apply(@NotNull ListSection<TargetExpression> targetSection) {
            return targetSection.items().contains(targetExpression);
          }
        });
      }

      return IssueOutput.error(matcher.group(0))
        .inFile(file)
        .build();
    }
  }

  static class InvalidTargetProjectViewPackageParser extends SingleLineParser {
    @Nullable private final ProjectViewSet projectViewSet;

    InvalidTargetProjectViewPackageParser(
      @Nullable ProjectViewSet projectViewSet,
      String regex) {
      super(regex);
      this.projectViewSet = projectViewSet;
    }

    @Override
    protected IssueOutput createIssue(@NotNull Matcher matcher) {
      File file = null;
      if (projectViewSet != null) {
        final String packageString = matcher.group(1);
        file = projectViewFileWithSection(projectViewSet, TargetSection.KEY, targetSection -> {
          for (TargetExpression targetExpression : targetSection.items()) {
            if (targetExpression.toString().startsWith("//" + packageString + ":")) {
              return true;
            }
          }
          return false;
        });
      }

      return IssueOutput.error(matcher.group(0))
        .inFile(file)
        .build();
    }
  }

  @Nullable
  private static <T, SectionType extends Section<T>> File projectViewFileWithSection(
    @NotNull ProjectViewSet projectViewSet,
    @NotNull SectionKey<T, SectionType> key,
    @NotNull Predicate<SectionType> predicate) {
    for (ProjectViewSet.ProjectViewFile projectViewFile : projectViewSet.getProjectViewFiles()) {
      SectionType section = projectViewFile.projectView.getSectionOfType(key);
      if (section != null && predicate.apply(section)) {
        return projectViewFile.projectViewFile;
      }
    }
    return null;
  }

  @NotNull private List<Parser> parsers = Lists.newArrayList();
  /** The parser that requested more lines of input during the last call to {@link #parseIssue(String)}. */
  @Nullable private Parser multilineMatchingParser;
  @NotNull private List<String> multilineMatchResult = new ArrayList<>();

  public BlazeIssueParser(
    @Nullable Project project,
    @NotNull WorkspaceRoot workspaceRoot) {

    ProjectViewSet projectViewSet = project != null ? ProjectViewManager.getInstance(project).getProjectViewSet() : null;

    parsers.add(new CompileParser(workspaceRoot));
    parsers.add(new TracebackParser());
    parsers.add(new BuildParser());
    parsers.add(new LinelessBuildParser());
    parsers.add(new ProjectViewLabelParser(projectViewSet));
    parsers.add(new InvalidTargetProjectViewPackageParser(projectViewSet, "no such package '(.*)': BUILD file not found on package path"));
    parsers.add(new InvalidTargetProjectViewPackageParser(projectViewSet, "no targets found beneath '(.*)'"));
    parsers.add(new InvalidTargetProjectViewPackageParser(projectViewSet, "ERROR: invalid target format '(.*)'"));
  }


  @Nullable
  public IssueOutput parseIssue(String line) {

    List<Parser> parsers = this.parsers;
    if (multilineMatchingParser != null) {
      parsers = Lists.newArrayList(multilineMatchingParser);
    }

    for (Parser parser : parsers) {
      ParseResult issue = parser.parse(line, multilineMatchResult);
      if (issue.needsMoreInput) {
        multilineMatchingParser = parser;
        multilineMatchResult.add(line);
        return null;
      }
      else {
        multilineMatchingParser = null;
        multilineMatchResult = new ArrayList<>();
      }

      if (issue.output != null) {
        return issue.output;
      }
    }

    return null;
  }
}
