package de.thetaphi.forbiddenapis.gradle;

/*
 * (C) Copyright Uwe Schindler (Generics Policeman) and others.
 *
 * 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.
 */

import java.io.File;

import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.plugins.PluginInstantiationException;
import org.gradle.api.tasks.TaskContainer;

/**
 * Forbiddenapis Gradle Plugin
 * @since 1.9
 */
public class GradlePlugin implements Plugin<Project> {
  
  static final String FORBIDDEN_APIS_TASK_NAME = "forbiddenApis";
  static final String TEST_FORBIDDEN_APIS_TASK_NAME = "testForbiddenApis";
  
  public void apply(final Project project) {
    if (project.getPlugins().findPlugin("java") == null) {
      throw new PluginInstantiationException("forbiddenapis only works in projects using the 'java' plugin.");
    }
    
    final ConfigurationContainer configurations = project.getConfigurations();
    final TaskContainer tasks = project.getTasks();
    
    // Get the tasks we depend on or the other one should depends on us (to insert us into the chain):
    final Task classesJavaTask = tasks.getByName("classes"),
        testClassesJavaTask = tasks.getByName("testClasses"),
        jarJavaTask = tasks.getByName("jar"),
        testJavaTask = tasks.getByName("test"),
        checkJavaTask = tasks.getByName("check");
    
    // Create the tasks of the plugin:
    final Task forbiddenTask = tasks.create(FORBIDDEN_APIS_TASK_NAME, GradleTask.class, new Action<GradleTask>() {
      public void execute(GradleTask task) {
        task.classesDir = (File) project.property("sourceSets.main.output.classesDir");
        task.classpath = configurations.getByName("compile");
        task.dependsOn(classesJavaTask);
      }
    });
    final Task testForbiddenTask = tasks.create(TEST_FORBIDDEN_APIS_TASK_NAME, GradleTask.class, new Action<GradleTask>() {
      public void execute(GradleTask task) {
        task.classesDir = (File) project.property("sourceSets.test.output.classesDir");
        task.classpath = configurations.getByName("testCompile");
        task.dependsOn(testClassesJavaTask);
      }
    });
    
    // Add dependencies
    jarJavaTask.dependsOn(forbiddenTask);
    testJavaTask.dependsOn(forbiddenTask, testForbiddenTask);
    checkJavaTask.dependsOn(forbiddenTask, testForbiddenTask);
  }
}

@@ -710,24 +710,75 @@
 api.Action;%0A
+import org.gradle.api.NamedDomainObjectCollection;%0A
 import org.g
@@ -1127,16 +1127,23 @@
  %7B%0A  %0A  
+public 
 static f
@@ -1200,16 +1200,23 @@
 pis%22;%0A  
+public 
 static f
@@ -1433,17 +1433,17 @@
 eption(%22
-f
+F
 orbidden
@@ -1766,28 +1766,24 @@
 Task classes
-Java
 Task = tasks
@@ -1820,28 +1820,24 @@
  testClasses
-Java
 Task = tasks
@@ -1870,28 +1870,24 @@
 %0A        jar
-Java
 Task = tasks
@@ -1913,28 +1913,24 @@
         test
-Java
 Task = tasks
@@ -1958,28 +1958,24 @@
        check
-Java
 Task = tasks
@@ -1996,24 +1996,211 @@
 eck%22);%0A    %0A
+    // Get classes directories for main and test%0A    final File mainClassesDir = getClassesDirByName(project, %22main%22),%0A        testClassesDir = getClassesDirByName(project, %22test%22);%0A    %0A
     // Creat
@@ -2416,57 +2416,13 @@
 r = 
-(File) project.property(%22sourceSets.main.output.c
+mainC
 lass
@@ -2418,34 +2418,32 @@
 = mainClassesDir
-%22)
 ;%0A        task.c
@@ -2516,28 +2516,24 @@
 dsOn(classes
-Java
 Task);%0A     
@@ -2742,57 +2742,13 @@
 r = 
-(File) project.property(%22sourceSets.test.output.c
+testC
 lass
@@ -2752,18 +2752,16 @@
 assesDir
-%22)
 ;%0A      
@@ -2810,32 +2810,68 @@
 e(%22testCompile%22)
+.plus(project.files(mainClassesDir))
 ;%0A        task.d
@@ -2890,20 +2890,16 @@
 tClasses
-Java
 Task);%0A 
@@ -2929,16 +2929,29 @@
  // Add 
+our tasks as 
 dependen
@@ -2958,16 +2958,25 @@
 cies
+ to chain
 %0A    jar
 Java
@@ -2971,20 +2971,16 @@
 %0A    jar
-Java
 Task.dep
@@ -3010,20 +3010,16 @@
     test
-Java
 Task.dep
@@ -3073,12 +3073,8 @@
 heck
-Java
 Task
@@ -3123,10 +3123,538 @@
 k);%0A  %7D%0A
+  %0A  private File getClassesDirByName(Project project, String sourceSetName) %7B%0A    final Object sourceSet = ((NamedDomainObjectCollection%3C?%3E) project.property(%22sourceSets%22)).getByName(sourceSetName);%0A    try %7B%0A      final Object output = sourceSet.getClass().getMethod(%22getOutput%22).invoke(sourceSet);%0A      return (File) output.getClass().getMethod(%22getClassesDir%22).invoke(output);%0A    %7D catch (Exception e) %7B%0A      throw new PluginInstantiationException(%22Forbiddenapis was not able to initialize classesDir.%22, e);%0A    %7D%0A  %7D%0A  %0A
 %7D%0A

Fix lookup of classesDir (horrible in plain Java); add main classesDir to test classpath