package org.eclipse.juno.tests;

import java.io.IOException;
import java.net.URISyntaxException;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.juno.tests.jars.BREETest;
import org.eclipse.juno.tests.jars.ESTest;
import org.eclipse.juno.tests.jars.Pack200Test;
import org.eclipse.juno.tests.jars.TestLayoutTest;
import org.eclipse.juno.tests.jars.VersionTest;
import org.eclipse.juno.tests.repos.FeatureDisplayableDataChecker;
import org.eclipse.juno.tests.repos.FeatureNameLengths;
import org.eclipse.juno.tests.repos.IUNameChecker;
import org.eclipse.juno.tests.repos.ProviderNameChecker;
import org.eclipse.juno.tests.repos.VersionChecking;

public class RunAllReportsAntTask extends Task {

    private String  directoryToCheck;
    private String  tempWorkingDir;
    private String  outputResultsDirectory;
    private boolean failuresOccurred = false;

    @Override
    public void execute() throws BuildException {

        try {


            String repoToTest = "file://" + getDirectoryToCheck();

            boolean uniquenessCheck = false;
            boolean featureNameFailures = false;
            boolean bundleNameFailures = false;
            boolean providerNamesFailure = false;
            boolean licenseConsistencyFailure = false;
            try {

                VersionChecking uniquenessChecker = new VersionChecking();
                uniquenessChecker.setRepoURLToTest(repoToTest);
                uniquenessChecker.setOutputDirectory(getOutputResultsDirectory());
                uniquenessCheck = uniquenessChecker.testVersionUniqness();
                if (uniquenessCheck) {
                    setFailuresOccurred(true);
                }

                IUNameChecker iuNames = new IUNameChecker();
                iuNames.setRepoURLToTest(repoToTest);
                iuNames.setOutputDirectory(getOutputResultsDirectory());
                featureNameFailures = iuNames.testFeatureNames();
                bundleNameFailures = iuNames.testBundleNames();

                ProviderNameChecker providerNameChecker = new ProviderNameChecker();
                providerNameChecker.setRepoURLToTest(repoToTest);
                providerNameChecker.setOutputDirectory(getOutputResultsDirectory());
                providerNamesFailure = providerNameChecker.testProviderNames();

                FeatureDisplayableDataChecker licenseChecker = new FeatureDisplayableDataChecker();
                licenseChecker.setRepoURLToTest(repoToTest);
                licenseChecker.setOutputDirectory(getOutputResultsDirectory());
                licenseConsistencyFailure = licenseChecker.testDisplayableData();

                FeatureNameLengths featureNameLengths = new FeatureNameLengths();
                featureNameLengths.setRepoURLToTest(repoToTest);
                featureNameLengths.setOutputDirectory(getOutputResultsDirectory());
                featureNameLengths.testFeatureDirectoryLength();

            }
            catch (ProvisionException e) {
                throw new BuildException(e);
            }
            catch (OperationCanceledException e) {
                throw new BuildException(e);
            }
            catch (URISyntaxException e) {
                throw new BuildException(e);
            }

            if (featureNameFailures || bundleNameFailures || providerNamesFailure || licenseConsistencyFailure) {
                setFailuresOccurred(true);
            }


            ESTest esTest = new ESTest();
            esTest.setDirectoryToCheck(getDirectoryToCheck());
            esTest.setTempWorkingDir(getTempWorkingDir());
            esTest.setOutputDirectory(getOutputResultsDirectory());

            boolean esFailures = esTest.testESSettingRule();

            if (esFailures) {
                setFailuresOccurred(true);
            }

            BREETest breeTest = new BREETest();
            breeTest.setDirectoryToCheck(getDirectoryToCheck());
            breeTest.setTempWorkingDir(getTempWorkingDir());
            breeTest.setOutputDirectory(getOutputResultsDirectory());

            boolean breeFailures = breeTest.testBREESettingRule();

            if (breeFailures) {
                setFailuresOccurred(true);
            }


            Pack200Test packTest = new Pack200Test();
            packTest.setDirectoryToCheck(getDirectoryToCheck());
            packTest.setOutputDirectory(getOutputResultsDirectory());
            boolean packFailures = packTest.testBundlePack();
            if (packFailures) {
                setFailuresOccurred(true);
            }


            VersionTest versionTest = new VersionTest();
            versionTest.setDirectoryToCheck(getDirectoryToCheck());
            versionTest.setOutputDirectory(getOutputResultsDirectory());
            boolean versionCheck = versionTest.testVersionsPatterns();
            if (versionCheck) {
                setFailuresOccurred(true);
            }


            TestLayoutTest test = new TestLayoutTest();
            test.setDirectoryToCheck(getDirectoryToCheck());
            test.setTempWorkingDir(getTempWorkingDir());
            test.setOutputDirectory(getOutputResultsDirectory());
            boolean layoutFailures = test.testLayout();
            if (layoutFailures) {
                setFailuresOccurred(true);
            }

        }
        catch (IOException e) {
            throw new BuildException(e);
        }
    }

    public String getDirectoryToCheck() {
        return directoryToCheck;
    }

    public void setDirectoryToCheck(String bundleDirToCheck) {
        this.directoryToCheck = bundleDirToCheck;
    }

    public String getTempWorkingDir() {
        return tempWorkingDir;
    }

    public void setTempWorkingDir(String tempWorkingDir) {
        this.tempWorkingDir = tempWorkingDir;
    }

    public boolean isFailuresOccurred() {
        return failuresOccurred;
    }

    public void setFailuresOccurred(boolean failuresOccurred) {
        this.failuresOccurred = failuresOccurred;
    }

    public String getOutputResultsDirectory() {
        return outputResultsDirectory;
    }

    public void setOutputResultsDirectory(String outputResultsDirectory) {
        this.outputResultsDirectory = outputResultsDirectory;
    }

}
