package com.google.common.html.plugin.css;

import java.io.File;
import java.io.IOException;

import javax.annotation.Nullable;

import org.apache.maven.plugin.logging.Log;

import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.css.ExitCodeHandler;
import com.google.common.css.JobDescription;
import com.google.common.css.SubstitutionMapProvider;
import com.google.common.css.compiler.ast.ErrorManager;
import com.google.common.css.compiler.ast.GssError;
import com.google.common.css.compiler.commandline.ClosureCommandLineCompiler;
import com.google.common.html.plugin.Sources;
import com.google.common.io.Files;

final class CssCompilerWrapper {
  private CssOptions cssOptions = new CssOptions();
  private ImmutableList<Sources.Source> inputs = ImmutableList.of();
  private Optional<File> outputFile = Optional.absent();
  private Optional<File> renameFile = Optional.absent();
  private Optional<File> sourceMapFile = Optional.absent();
  private SubstitutionMapProvider substitutionMapProvider;

  CssCompilerWrapper cssOptions(CssOptions newCssOptions) {
    this.cssOptions = newCssOptions;
    return this;
  }
  CssCompilerWrapper inputs(Iterable<? extends Sources.Source> newInputs) {
    this.inputs = ImmutableList.copyOf(newInputs);
    return this;
  }
  CssCompilerWrapper outputFile(File newOutputFile) {
    this.outputFile = Optional.of(newOutputFile);
    return this;
  }
  CssCompilerWrapper renameFile(File newRenameFile) {
    this.renameFile = Optional.of(newRenameFile);
    return this;
  }
  CssCompilerWrapper substitutionMapProvider(
      SubstitutionMapProvider newSubstitutionMapProvider) {
    this.substitutionMapProvider = newSubstitutionMapProvider;
    return this;
  }
  CssCompilerWrapper sourceMapFile(File newSourceMapFile) {
    this.sourceMapFile = Optional.of(newSourceMapFile);
    return this;
  }

  boolean compileCss(final Log log) throws IOException {
    if (inputs.isEmpty()) {
      log.info("No CSS files to compile");
      return true;
    }
    log.info("Compiling " + inputs.size() + " CSS files" +
        (outputFile.isPresent() ? " to " + outputFile.get().getPath() : ""));

    JobDescription job = cssOptions.getJobDescription(
        log, inputs, substitutionMapProvider);

    final class OkUnlessNonzeroExitCodeHandler implements ExitCodeHandler {
      boolean ok = true;

      public void processExitCode(int exitCode) {
        if (exitCode != 0) {
          ok = false;
        }
      }
    }

    OkUnlessNonzeroExitCodeHandler exitCodeHandler =
        new OkUnlessNonzeroExitCodeHandler();

    ErrorManager errorManager = new MavenCssErrorManager(log);

    final class Compiler extends ClosureCommandLineCompiler {
      Compiler(
          JobDescription job,
          ExitCodeHandler exitCodeHandler,
          ErrorManager errManager) {
        super(job, exitCodeHandler, errManager);
      }

      @Override
      public String execute(
          @Nullable File renameFilePath, @Nullable File sourceMapFilePath) {
        return super.execute(renameFilePath, sourceMapFilePath);
      }
    }

    String compiledCss = new Compiler(job, exitCodeHandler, errorManager)
        .execute(renameFile.orNull(), sourceMapFile.orNull());
    if (compiledCss == null) {
      return false;
    }
    if (outputFile.isPresent()) {
      Files.write(compiledCss, outputFile.get(), Charsets.UTF_8);
    }
    return exitCodeHandler.ok;
  }
}

final class MavenCssErrorManager implements ErrorManager {
  private boolean hasErrors;
  private final Log log;

  MavenCssErrorManager(Log log) {
    this.log = log;
  }

  public void report(GssError error) {
    hasErrors = true;
    log.error(error.format());
  }

  public void reportWarning(GssError warning) {
    log.warn(warning.format());
  }

  public void generateReport() {
    // Errors reported eagerly.
    // TODO(summarize something)?
  }

  public boolean hasErrors() {
    return hasErrors;
  }
}

@@ -91,43 +91,8 @@
 n;%0A%0A
-import javax.annotation.Nullable;%0A%0A
 impo
@@ -2699,481 +2699,59 @@
     
-final class Compiler extends ClosureCommandLineCompiler %7B%0A      Compiler(%0A          JobDescription job,%0A          ExitCodeHandler exitCodeHandler,%0A          ErrorManager errManager) %7B%0A        super(job, exitCodeHandler, errManager);%0A      %7D%0A%0A      @Override%0A      public String execute(%0A          @Nullable File renameFilePath, @Nullable File sourceMapFilePath) %7B%0A        return super.execute(renameFilePath, sourceMapFilePath);%0A      %7D%0A    %7D%0A%0A    String compiledCss = new 
+String compiledCss =%0A        new ClosureCommandLine
 Comp

use accessible stylesheet compiler ctor instead of subclassing