/*
 * Copyright 2009 the original author or authors.
 *
 * 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 org.gradle.integtests;

import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.junit.runners.model.FrameworkMethod;
import org.gradle.api.UncheckedIOException;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;

public class DistributionIntegrationTestRunner extends BlockJUnit4ClassRunner {
    private static GradleDistribution dist;

    public DistributionIntegrationTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
    }

    @Override
    protected Statement withBefores(FrameworkMethod method, final Object target, Statement statement) {
        final Statement setup = super.withBefores(method, target, statement);
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                attachDistribution(target);
                setup.evaluate();
            }
        };
    }

    private void attachDistribution(Object target) throws Exception {
        GradleDistribution distribution = getDist();
        injectValue(target, distribution, GradleDistribution.class);
        injectValue(target, new ForkingGradleExecuter(distribution), GradleExecuter.class);
    }

    private void injectValue(Object target, Object value, Class<?> type) throws IllegalAccessException {
        for (Class<?> current = target.getClass(); current != null; current = current.getSuperclass()) {
            for (Field field : current.getDeclaredFields()) {
                if (field.getType().equals(type)) {
                    field.setAccessible(true);
                    field.set(target, value);
                }
            }
        }
    }

    private static GradleDistribution getDist() throws IOException {
        if (dist == null) {
            final File gradleHomeDir = file("integTest.gradleHomeDir", new File("build/distributions/exploded"));
            final File samplesDir = new File(gradleHomeDir, "samples");
            File srcDir = file("integTest.srcDir", new File("src"));
            final File userGuideOutputDir = new File(srcDir, "samples/userguideOutput");
            final File userGuideInfoDir = file("integTest.userGuideInfoDir", new File("build/docbook/src"));

            dist = new GradleDistribution() {
                public File getGradleHomeDir() {
                    return gradleHomeDir;
                }

                public File getSamplesDir() {
                    return samplesDir;
                }

                public File getUserGuideInfoDir() {
                    return userGuideInfoDir;
                }

                public File getUserGuideOutputDir() {
                    return userGuideOutputDir;
                }
            };
        }
        return dist;
    }

    private static File file(String propertyName, File defaultFile) {
        String path = System.getProperty(propertyName, defaultFile.getAbsolutePath());
        try {
            return new File(path).getCanonicalFile();
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
}

@@ -832,16 +832,103 @@
 Method;%0A
+import org.junit.runner.notification.RunNotifier;%0Aimport org.junit.runner.Description;%0A
 import o
@@ -963,16 +963,16 @@
 eption;%0A
-
 %0Aimport 
@@ -1044,16 +1044,67 @@
 t.Field;
+%0Aimport java.util.List;%0Aimport java.util.ArrayList;
 %0A%0Apublic
@@ -1312,24 +1312,24 @@
 tionError %7B%0A
-
         supe
@@ -1345,24 +1345,407 @@
 ss);%0A    %7D%0A%0A
+    @Override%0A    public void run(final RunNotifier notifier) %7B%0A        if (System.getProperty(%22org.gradle.integtest.ignore%22) != null) %7B%0A            notifier.fireTestIgnored(Description.createTestDescription(getTestClass().getJavaClass(),%0A                    %22System property to ignore integration tests is set.%22));%0A        %7D else %7B%0A            super.run(notifier);%0A        %7D%0A    %7D%0A%0A
     @Overrid

Add switch for ignoring distribution integration tests.