package org.jetbrains.groovy.compiler.rt;

/*
 * Copyright 2000-2007 JetBrains s.r.o.
 * 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.
 */

import groovy.lang.GroovyRuntimeException;
import org.codehaus.groovy.GroovyBugError;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.control.*;
import org.codehaus.groovy.control.messages.*;
import org.codehaus.groovy.syntax.SyntaxException;
import org.codehaus.groovy.tools.GroovyClass;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;


public class GroovyCompilerWrapper {
  private static final String LINKAGE_ERROR =
    "A groovyc error occurred while trying to load one of the classes in project dependencies, please ensure it's present. " +
    "See the message and the stack trace below for reference\n\n";
  private final List<CompilerMessage> collector;
  private final boolean forStubs;

  public GroovyCompilerWrapper(List<CompilerMessage> collector, boolean forStubs) {
    this.collector = collector;
    this.forStubs = forStubs;
  }

  public List<OutputItem> compile(final CompilationUnit unit) {
    List<OutputItem> compiledFiles = new ArrayList<OutputItem>();
    try {
      unit.compile(forStubs ? Phases.CONVERSION : Phases.ALL);
      addCompiledFiles(unit, compiledFiles, forStubs);
    }
    catch (CompilationFailedException e) {
      processCompilationException(e);
    }
    catch (IOException e) {
      processException(e, "");
    }
    catch (GroovyBugError e) {
      processException(e, "");
    }
    catch (NoClassDefFoundError e) {
      final String className = e.getMessage();
      if (className.startsWith("org/apache/ivy/")) {
        addMessageWithoutLocation("Cannot @Grab without Ivy, please add it to your module dependencies (NoClassDefFoundError: " + className + ")", true);
      } else {
        throw e;
      }

    }
    catch (TypeNotPresentException e) {
      processException(e, LINKAGE_ERROR);
    }
    catch (LinkageError e) {
      processException(e, LINKAGE_ERROR);
    }
    finally {
      addWarnings(unit.getErrorCollector());
    }
    return compiledFiles;
  }

  private static void addCompiledFiles(CompilationUnit compilationUnit,
                                       final List<OutputItem> compiledFiles,
                                       final boolean forStubs) throws IOException {
    File targetDirectory = compilationUnit.getConfiguration().getTargetDirectory();

    final String outputPath = targetDirectory.getCanonicalPath().replace(File.separatorChar, '/');

    if (forStubs) {
      compilationUnit.applyToPrimaryClassNodes(new CompilationUnit.PrimaryClassNodeOperation() {
        public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
          final String topLevel = classNode.getName();
          final String stubPath = outputPath + "/" + topLevel.replace('.', '/') + ".java";
          String fileName = source.getName();
          if (fileName.startsWith("file:")) {
            try {
              fileName = new URL(fileName).getFile();
            }
            catch (MalformedURLException ignored) {
            }
          }
          if (new File(stubPath).exists()) {
            compiledFiles.add(new OutputItem(stubPath, fileName));
          }
          /*
          else {
            collector.add(new CompilerMessage(CompilerMessage.WARNING, "Groovyc didn't generate stub for " + topLevel, fileName,
                                              classNode.getLineNumber(), classNode.getColumnNumber()));
          }
          */
        }
      });
      return;
    }

    final SortedSet<String> allClasses = new TreeSet<String>();
    //noinspection unchecked
    List<GroovyClass> listOfClasses = compilationUnit.getClasses();
    for (GroovyClass listOfClass : listOfClasses) {
      allClasses.add(listOfClass.getName());
    }

    for (Iterator iterator = compilationUnit.iterator(); iterator.hasNext();) {
      SourceUnit sourceUnit = (SourceUnit) iterator.next();
      String fileName = sourceUnit.getName();
      //for debug purposes
      //System.out.println("source: " + fileName);
      //System.out.print("classes:");
      final ModuleNode ast = sourceUnit.getAST();
      final List<ClassNode> topLevelClasses = ast.getClasses();

      for (ClassNode classNode : topLevelClasses) {
        final String topLevel = classNode.getName();
        final String nested = topLevel + "$";
        final SortedSet<String> tail = allClasses.tailSet(topLevel);
        for (Iterator<String> tailItr = tail.iterator(); tailItr.hasNext(); ) {
          String className = tailItr.next();
          if (className.equals(topLevel) || className.startsWith(nested)) {
            tailItr.remove();
            compiledFiles.add(new OutputItem(outputPath + "/" + className.replace('.', '/') + ".class", fileName));
          }
          else {
            break;
          }
        }
      }
    }
  }

  private void addWarnings(ErrorCollector errorCollector) {
    for (int i = 0; i < errorCollector.getWarningCount(); i++) {
      WarningMessage warning = errorCollector.getWarning(i);
      collector.add(new CompilerMessage(GroovyCompilerMessageCategories.WARNING, warning.getMessage(), null, -1, -1));
    }
  }

  private void processCompilationException(Exception exception) {
    if (exception instanceof MultipleCompilationErrorsException) {
      MultipleCompilationErrorsException multipleCompilationErrorsException = (MultipleCompilationErrorsException) exception;
      ErrorCollector errorCollector = multipleCompilationErrorsException.getErrorCollector();
      for (int i = 0; i < errorCollector.getErrorCount(); i++) {
        processException(errorCollector.getError(i));
      }
    } else {
      processException(exception, "");
    }
  }

  /** @noinspection ThrowableResultOfMethodCallIgnored*/
  private void processException(Message message) {
    if (message instanceof SyntaxErrorMessage) {
      SyntaxErrorMessage syntaxErrorMessage = (SyntaxErrorMessage) message;
      addErrorMessage(syntaxErrorMessage.getCause());
    } else if (message instanceof ExceptionMessage) {
      ExceptionMessage exceptionMessage = (ExceptionMessage) message;
      processException(exceptionMessage.getCause(), "");
    } else if (message instanceof SimpleMessage) {
      addErrorMessage((SimpleMessage) message);
    } else {
      addMessageWithoutLocation("An unknown error occurred: " + message, true);
    }
  }

  private void processException(Throwable exception, String prefix) {
    if (exception instanceof GroovyRuntimeException) {
      addErrorMessage((GroovyRuntimeException) exception);
      return;
    }

    if (forStubs) {
      collector.add(new CompilerMessage(GroovyCompilerMessageCategories.INFORMATION,
                                        "Groovyc stub generation failed", null, -1, -1));
    }

    final StringWriter writer = new StringWriter();
    writer.append(prefix);
    //noinspection IOResourceOpenedButNotSafelyClosed
    exception.printStackTrace(new PrintWriter(writer));
    collector.add(new CompilerMessage(forStubs ? GroovyCompilerMessageCategories.INFORMATION : GroovyCompilerMessageCategories.ERROR, writer.toString(), null, -1, -1));
  }

  private void addMessageWithoutLocation(String message, boolean error) {
    collector.add(new CompilerMessage(error ? GroovyCompilerMessageCategories.ERROR : GroovyCompilerMessageCategories.WARNING, message, null, -1, -1));
  }

  private static final String LINE_AT = " @ line ";

  private void addErrorMessage(SyntaxException exception) {
    String message = exception.getMessage();
    String justMessage = message.substring(0, message.lastIndexOf(LINE_AT));
    collector.add(new CompilerMessage(GroovyCompilerMessageCategories.ERROR, justMessage, exception.getSourceLocator(),
        exception.getLine(), exception.getStartColumn()));
  }

  private void addErrorMessage(GroovyRuntimeException exception) {
    ASTNode astNode = exception.getNode();
    ModuleNode module = exception.getModule();
    if (module == null) {
      module = findModule(astNode);
    }
    String moduleName = module == null ? "<no module>" : module.getDescription();

    int lineNumber = astNode == null ? -1 : astNode.getLineNumber();
    int columnNumber = astNode == null ? -1 : astNode.getColumnNumber();

    String message = exception.getMessageWithoutLocationText();
    if (message == null) {
      StringWriter stringWriter = new StringWriter();
      //noinspection IOResourceOpenedButNotSafelyClosed
      PrintWriter writer = new PrintWriter(stringWriter);
      exception.printStackTrace(writer);
      message = stringWriter.getBuffer().toString();
    }

    collector.add(new CompilerMessage(GroovyCompilerMessageCategories.ERROR, message, moduleName, lineNumber, columnNumber));
  }

  private static ModuleNode findModule(ASTNode node) {
    if (node instanceof ModuleNode) {
      return (ModuleNode)node;
    }
    if (node instanceof ClassNode) {
      return ((ClassNode)node).getModule();
    }
    if (node instanceof AnnotatedNode) {
      return ((AnnotatedNode)node).getDeclaringClass().getModule();
    }
    return null;
  }

  private void addErrorMessage(SimpleMessage message) {
    addMessageWithoutLocation(message.getMessage(), true);
  }

  public static class OutputItem {
    private final String myOutputPath;
    private final String mySourceFileName;

    public OutputItem(String outputPath, String sourceFileName) {
      myOutputPath = outputPath;
      mySourceFileName = sourceFileName;
    }

    public String getOutputPath() {
      return myOutputPath;
    }

    public String getSourceFile() {
      return mySourceFileName;
    }
  }
}
