/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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.
*/
 
task jacocoTestReport {
  description = "Generates a coverage report from all subprojects (use after 'test')"
  ext.test7AdjustJacocoReport = false
}
jacocoTestReport << {

  ant.delete(dir: "${target_report_dir}/coverage")

  def libDir = new File("${target_java8_dir}", "lib")
  def utilsDir = new File("${target_java8_dir}", "utils")
  def connectorsDir = new File("${target_java8_dir}", "connectors")
  def analyticsDir = new File("${target_java8_dir}", "analytics")
  def consoleDir = new File("${target_java8_dir}", "console")

  if( !libDir.exists() ) { libDir.mkdirs() }
  if( !utilsDir.exists() ) { utilsDir.mkdirs() }
  if( !connectorsDir.exists() ) { connectorsDir.mkdirs() }
  if( !analyticsDir.exists() ) { analyticsDir.mkdirs() }
  if( !consoleDir.exists() ) { consoleDir.mkdirs() }

  FileCollection executionData = files()

  subprojects.findAll { subproject ->
    subproject.pluginManager.hasPlugin('java') && subproject.pluginManager.hasPlugin('jacoco')
  }.each { subproject ->
    executionData += subproject.tasks.jacocoTestReport.executionData
  }

  executionData = files(executionData.findAll {
    it.exists()
  })
  ant.taskdef(name: 'jacocoReport', classname: 'org.jacoco.ant.ReportTask',
          classpath: configurations.junitLibs.asPath)
  ant.jacocoReport {
    executiondata {
      executionData.addToAntBuilder(ant, 'resources')
    }

    platformTargetDir = target_java8_dir
    if (test7AdjustJacocoReport) {
      platformTargetDir = target_java7_dir
    }

    structure(name: project.name) {
      group(name: "Edgent API") {
        classfiles {
          fileset(dir: "$platformTargetDir/lib", includes: "edgent.api.*.jar")
        }
        sourcefiles {
          fileset(dir: "./api/function/src/main/java", includes: "**/*.java")
          fileset(dir: "./api/execution/src/main/java", includes: "**/*.java")
          fileset(dir: "./api/oplet/src/main/java", includes: "**/*.java")
          fileset(dir: "./api/graph/src/main/java", includes: "**/*.java")
          fileset(dir: "./api/topology/src/main/java", includes: "**/*.java")
        }
      }
      group(name: "Edgent SPI") {
        classfiles {
          fileset(dir: "$platformTargetDir/lib", includes: "edgent.spi.*.jar")
        }
        sourcefiles {
          fileset(dir: "./spi/graph/src/main/java", includes: "**/*.java")
          fileset(dir: "./spi/topology/src/main/java", includes: "**/*.java")
        }
      }
      group(name: "Edgent Runtime") {
        classfiles {
          fileset(dir: "$platformTargetDir/lib", includes: "edgent.runtime.*.jar")
        }
        sourcefiles {
          fileset(dir: "./runtime/etiao/src/main/java", includes: "**/*.java")
          fileset(dir: "./runtime/jmxcontrol/src/main/java", includes: "**/*.java")
        }
      }
      group(name: "Edgent Utilities") {
        classfiles {
          fileset(dir: "$platformTargetDir/utils", includes: "**/edgent.utils.*.jar")
        }
        sourcefiles {
          fileset(dir: "./utils/metrics/src/main/java", includes: "**/*.java")
          fileset(dir: "./utils/streamscope/src/main/java", includes: "**/*.java")
        }
      }
      group(name: "Edgent Connectors") {
        classfiles {
          fileset(dir: "$platformTargetDir/connectors", includes: "**/edgent.connectors.*.jar")
        }
        sourcefiles {
          fileset(dir: "./connectors/common/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/command/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/csv/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/file/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/iot/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/iotp/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/jdbc/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/kafka/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/mqtt/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/http/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/wsclient/src/main/java", includes: "**/*.java")
          fileset(dir: "./connectors/wsclient-javax.websocket/src/main/java", includes: "**/*.java")
        }
      }
      group(name: "Edgent Providers") {
        classfiles {
          fileset(dir: "$platformTargetDir/lib", includes: "edgent.providers.*.jar")
        }
        sourcefiles {
          fileset(dir: "./providers/direct/src/main/java", includes: "**/*.java")
          fileset(dir: "./providers/development/src/main/java", includes: "**/*.java")
        }
      }
      if (!test7AdjustJacocoReport) {
        group(name: "Edgent Analytics") {
          classfiles {
            fileset(dir: "$platformTargetDir/analytics", includes: "**/edgent.analytics.*.jar")
          }
          sourcefiles {
            fileset(dir: "./analytics/math3/src/main/java", includes: "**/*.java")
            fileset(dir: "./analytics/sensors/src/main/java", includes: "**/*.java")
          }
        }
        group(name: "Edgent Console") {
          classfiles {
            fileset(dir: "$platformTargetDir/console", includes: "**/edgent.console.*.jar")
          }
          sourcefiles {
            fileset(dir: "./console/server/src/main/java", includes: "**/*.java")
            fileset(dir: "./console/servlets/src/main/java", includes: "**/*.java")
          }
        }
      }
    }
    html(destdir: "${target_report_dir}/coverage/")
    xml(destfile: "${target_report_dir}/coverage/jacoco-sessions.xml")
  }
}
