/*
 * Copyright (C) 2009 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;

import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import vogar.tasks.BuildActionTask;
import vogar.tasks.PrepareTarget;
import vogar.tasks.PrepareUserDirTask;
import vogar.tasks.RetrieveFilesTask;
import vogar.tasks.RmTask;
import vogar.tasks.Task;
import vogar.util.TimeUtilities;

/**
 * Compiles, installs, runs and reports on actions.
 */
public final class Driver {
    private final Run run;

    public Driver(Run run) {
        this.run = run;
    }

    private int successes = 0;
    private int failures = 0;
    private int skipped = 0;
    private int warnings = 0;

    private Task prepareTargetTask;
    private Set<Task> installVogarTasks;

    private final Map<String, Action> actions = Collections.synchronizedMap(
            new LinkedHashMap<String, Action>());
    private final Map<String, Outcome> outcomes = Collections.synchronizedMap(
            new LinkedHashMap<String, Outcome>());
    public boolean recordResults = true;

    /**
     * Builds and executes the actions in the given files.
     */
    public boolean buildAndRun(Collection<File> files, Collection<String> classes) {
        if (!actions.isEmpty()) {
            throw new IllegalStateException("Drivers are not reusable");
        }

        run.mkdir.mkdirs(run.localTemp);

        filesToActions(files);
        classesToActions(classes);

        if (actions.isEmpty()) {
            run.console.info("Nothing to do.");
            return false;
        }

        run.console.info("Actions: " + actions.size());
        final long t0 = System.currentTimeMillis();

        prepareTargetTask = new PrepareTarget(run, run.target);
        run.taskQueue.enqueue(prepareTargetTask);

        installVogarTasks = run.mode.installTasks();
        run.taskQueue.enqueueAll(installVogarTasks);
        registerPrerequisites(Collections.singleton(prepareTargetTask), installVogarTasks);

        for (Action action : actions.values()) {
            action.setUserDir(new File(run.runnerDir, action.getName()));
            Outcome outcome = outcomes.get(action.getName());
            if (outcome != null) {
                addEarlyResult(outcome);
            } else if (run.expectationStore.get(action.getName()).getResult() == Result.UNSUPPORTED) {
                addEarlyResult(new Outcome(action.getName(), Result.UNSUPPORTED,
                    "Unsupported according to expectations file"));
            } else {
                enqueueActionTasks(action);
            }
        }

        if (run.cleanAfter) {
            Set<Task> shutdownTasks = new HashSet<Task>();
            shutdownTasks.add(new RmTask(run.rm, run.localTemp));
            shutdownTasks.add(run.target.rmTask(run.runnerDir));
            for (Task task : shutdownTasks) {
                task.after(run.taskQueue.getTasks());
            }
            run.taskQueue.enqueueAll(shutdownTasks);
        }

        run.taskQueue.printTasks();
        run.taskQueue.runTasks();
        if (run.taskQueue.hasFailedTasks()) {
            run.taskQueue.printProblemTasks();
            return false;
        }

        if (run.reportPrinter.isReady()) {
            run.console.info("Printing XML Reports... ");
            int numFiles = run.reportPrinter.generateReports(outcomes.values());
            run.console.info(numFiles + " XML files written.");
        }

        long t1 = System.currentTimeMillis();

        Map<String, AnnotatedOutcome> annotatedOutcomes = run.outcomeStore.read(this.outcomes);
        if (recordResults) {
            run.outcomeStore.write(outcomes);
        }

        run.console.summarizeOutcomes(annotatedOutcomes.values());

        List<String> jarStringList = run.jarSuggestions.getStringList();
        if (!jarStringList.isEmpty()) {
            run.console.warn(
                    "consider adding the following to the classpath:",
                    jarStringList);
        }

        if (failures > 0 || skipped > 0 || warnings > 0) {
            run.console.info(String.format(
                    "Outcomes: %s. Passed: %d, Failed: %d, Skipped: %d, Warnings: %d. Took %s.",
                    (successes + failures + warnings + skipped), successes, failures, skipped, warnings,
                    TimeUtilities.msToString(t1 - t0)));
        } else {
            run.console.info(String.format("Outcomes: %s. All successful. Took %s.",
                    successes, TimeUtilities.msToString(t1 - t0)));
        }
        return failures == 0;
    }

    private void enqueueActionTasks(Action action) {
        Expectation expectation = run.expectationStore.get(action.getName());
        boolean useLargeTimeout = expectation.getTags().contains("large");
        File jar = run.hostJar(action);

        Task build = new BuildActionTask(run, action, this, jar);
        run.taskQueue.enqueue(build);

        Task prepareUserDir = new PrepareUserDirTask(run.target, action);
        prepareUserDir.after(installVogarTasks);
        run.taskQueue.enqueue(prepareUserDir);

        Set<Task> install = run.mode.installActionTasks(action, jar);
        registerPrerequisites(Collections.singleton(build), install);
        registerPrerequisites(installVogarTasks, install);
        registerPrerequisites(Collections.singleton(prepareTargetTask), install);
        run.taskQueue.enqueueAll(install);

        Task execute = run.mode.executeActionTask(action, useLargeTimeout)
                .afterSuccess(installVogarTasks)
                .afterSuccess(build)
                .afterSuccess(prepareUserDir)
                .afterSuccess(install);
        run.taskQueue.enqueue(execute);

        Task retrieveFiles = new RetrieveFilesTask(run, action.getUserDir()).after(execute);
        run.taskQueue.enqueue(retrieveFiles);

        if (run.cleanAfter) {
            run.taskQueue.enqueue(new RmTask(run.rm, run.localFile(action))
                    .after(execute).after(retrieveFiles));
            Set<Task> cleanupTasks = run.mode.cleanupTasks(action);
            for (Task task : cleanupTasks) {
                task.after(execute).after(retrieveFiles);
            }
            run.taskQueue.enqueueAll(cleanupTasks);
        }
    }

    private void registerPrerequisites(Set<Task> allBefore, Set<Task> allAfter) {
        for (Task task : allAfter) {
            task.afterSuccess(allBefore);
        }
    }

    private void classesToActions(Collection<String> classNames) {
        for (String className : classNames) {
            Action action = new Action(className, className, null, null, null);
            actions.put(action.getName(), action);
        }
    }

    private void filesToActions(Collection<File> files) {
        for (File file : files) {
            new ActionFinder(run.console, actions, outcomes).findActions(file);
        }
    }

    public synchronized void addEarlyResult(Outcome earlyFailure) {
        if (earlyFailure.getResult() == Result.UNSUPPORTED) {
            run.console.verbose("skipped " + earlyFailure.getName());
            skipped++;

        } else {
            for (String line : earlyFailure.getOutputLines()) {
                run.console.streamOutput(earlyFailure.getName(), line + "\n");
            }
            recordOutcome(earlyFailure);
        }
    }

    public synchronized void recordOutcome(Outcome outcome) {
        outcomes.put(outcome.getName(), outcome);
        Expectation expectation = run.expectationStore.get(outcome);
        ResultValue resultValue = outcome.getResultValue(expectation);

        if (resultValue == ResultValue.OK) {
            successes++;
        } else if (resultValue == ResultValue.FAIL) {
            failures++;
        } else if (resultValue == ResultValue.WARNING) {
            warnings++;
        } else { // ResultValue.IGNORE
            skipped++;
        }

        Result result = outcome.getResult();
        run.console.outcome(outcome.getName());
        run.console.printResult(outcome.getName(), result, resultValue, expectation);

        JarSuggestions singleOutcomeJarSuggestions = new JarSuggestions();
        singleOutcomeJarSuggestions.addSuggestionsFromOutcome(outcome, run.classFileIndex,
                run.classpath);
        List<String> jarStringList = singleOutcomeJarSuggestions.getStringList();
        if (!jarStringList.isEmpty()) {
            run.console.warn(
                    "may have failed because some of these jars are missing from the classpath:",
                    jarStringList);
        }
        run.jarSuggestions.addSuggestions(singleOutcomeJarSuggestions);
    }
}
