/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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 vogar.tasks;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;

import com.google.common.collect.Sets;

import vogar.Action;
import vogar.Classpath;
import vogar.Driver;
import vogar.Mode;
import vogar.Outcome;
import vogar.Result;
import vogar.Run;
import vogar.TestProperties;
import vogar.Toolchain;
import vogar.commands.Command;
import vogar.commands.CommandFailedException;
import vogar.commands.Javac;

/**
 * Compiles classes for the given action and makes them ready for execution.
 */
public final class BuildActionTask extends Task {
    private static final Pattern JAVA_SOURCE_PATTERN = Pattern.compile("\\/(\\w)+\\.java$");

    private final Action action;
    private final Run run;
    private final Driver driver;
    private final File outputFile;

    public BuildActionTask(Run run, Action action, Driver driver, File outputFile) {
        super("build " + action.getName());
        this.run = run;
        this.action = action;
        this.driver = driver;
        this.outputFile = outputFile;
    }

    @Override protected Result execute() throws Exception {
        try {
            compile(action, outputFile);
            return Result.SUCCESS;
        } catch (CommandFailedException e) {
            driver.addEarlyResult(new Outcome(action.getName(), Result.COMPILE_FAILED,
                    e.getOutputLines()));
            return Result.COMPILE_FAILED;
        } catch (IOException e) {
            driver.addEarlyResult(new Outcome(action.getName(), Result.ERROR, e));
            return Result.ERROR;
        }
    }

    /**
     * Returns the .jar file containing the action's compiled classes.
     *
     * @throws CommandFailedException if javac fails
     */
    private void compile(Action action, File jar) throws IOException {
        File classesDir = run.localFile(action, "classes");
        run.mkdir.mkdirs(classesDir);
        createJarMetadataFiles(action, classesDir);

        Set<File> sourceFiles = new HashSet<File>();
        File javaFile = action.getJavaFile();
        Javac javac = new Javac(run.log, run.javaPath("javac"));
        if (run.debugging) {
            javac.debug();
        }
        if (javaFile != null) {
            if (!JAVA_SOURCE_PATTERN.matcher(javaFile.toString()).find()) {
                throw new CommandFailedException(Collections.<String>emptyList(),
                        Collections.singletonList("Cannot compile: " + javaFile));
            }
            sourceFiles.add(javaFile);
            Classpath sourceDirs = Classpath.of(action.getSourcePath());
            sourceDirs.addAll(run.sourcepath);
            javac.sourcepath(sourceDirs.getElements());
        }
        if (!sourceFiles.isEmpty()) {
            if (!run.buildClasspath.isEmpty()) {
                javac.bootClasspath(run.buildClasspath);
            }
            javac.classpath(run.classpath)
                    .destination(classesDir)
                    .javaVersion(run.language.getJavacSourceAndTarget())
                    .extra(run.javacArgs)
                    .compile(sourceFiles);
        }

        new Command(run.log, run.javaPath("jar"), "cvfM", jar.getPath(),
                "-C", classesDir.getPath(), "./").execute();
    }

    /**
     * Writes files to {@code classesDir} to be included in the .jar file for
     * {@code action}.
     */
    private void createJarMetadataFiles(Action action, File classesDir) throws IOException {
        OutputStream propertiesOut
                = new FileOutputStream(new File(classesDir, TestProperties.FILE));
        Properties properties = new Properties();
        fillInProperties(properties, action);
        properties.store(propertiesOut, "generated by " + Mode.class.getName());
        propertiesOut.close();
    }

    /**
     * Fill in properties for running in this mode
     */
    private void fillInProperties(Properties properties, Action action) {
        properties.setProperty(TestProperties.TEST_CLASS_OR_PACKAGE, action.getTargetClass());
        properties.setProperty(TestProperties.MONITOR_PORT, Integer.toString(run.firstMonitorPort));
        properties.setProperty(TestProperties.TIMEOUT, Integer.toString(run.timeoutSeconds));
        properties.setProperty(TestProperties.RUNNER_TYPE, run.runnerType.toString());
    }
}
