/*
 * 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();
        run.taskQueue.printProblemTasks();

        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);
    }
}
