/*
 * 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.
 */

/*
 * Master Gradle initialization script
 *
 * Depends on bnd_* values from gradle.properties.
 */

import aQute.bnd.build.Workspace

/* Add bnd as a script dependency */
buildscript {
  dependencies {
    def bndURI = rootDir.toURI().resolve(bnd_jar)
    if (bndURI.scheme != 'file') {
      /* If not a local file, copy to a local file in cnf/cache */
      def cnfCache = mkdir("${rootDir}/${bnd_cnf}/cache")
      def bndJarFile = new File(cnfCache, 'biz.aQute.bnd.gradle.jar')
      if (!bndJarFile.exists()) {
        println "Downloading ${bndURI} to ${bndJarFile} ..."
        bndURI.toURL().withInputStream { is ->
          bndJarFile.withOutputStream { os ->
            def bos = new BufferedOutputStream( os )
            bos << is
          }
        }
      }
      bndURI = bndJarFile.toURI()
    }
    classpath files(bndURI)

    /* After the rootProject is created, pass URI to projects */
    gradle.rootProject { rootProject ->
      rootProject.ext.bndURI = bndURI
    }
  }
}

/* Initialize the bnd workspace */
def workspace = Workspace.getWorkspace(rootDir, bnd_cnf)
if (workspace == null) {
  throw new GradleException("Unable to load workspace ${rootDir}/${bnd_cnf}")
}

/* Add cnf project to the graph */
include bnd_cnf

/* Start with the declared build project name */
def defaultProjectName = bnd_build

/* If in a subproject, use the subproject name */
for (def currentDir = startParameter.currentDir; currentDir != rootDir; currentDir = currentDir.parentFile) {
  defaultProjectName = currentDir.name
}

/* Build a set of project names we need to include from the specified tasks */
def projectNames = startParameter.taskNames.collect { taskName ->
  def elements = taskName.split(':')
  switch (elements.length) {
    case 1:
      return defaultProjectName
    case 2:
      return elements[0].empty ? bnd_build : elements[0]
    default:
      return elements[0].empty ? elements[1] : elements[0]
  }
}.toSet()

/* Include the default project name if in a subproject or no tasks specified */
if ((startParameter.currentDir != rootDir) || projectNames.empty) {
  projectNames += defaultProjectName
}

/* If bnd_build used but declared empty, add all non-private folders of rootDir */
if (projectNames.remove('')) {
  rootDir.eachDir {
    def projectName = it.name
    if (!projectName.startsWith('.')) {
      projectNames += projectName
    }
  }
}

/* Add each project and its dependencies to the graph */
projectNames.each { projectName ->
  // Don't build the org.apache.felix.dependencymanager.benchmark, which requires java8 (build the benchmark bundle only makes sense within eclipse
  if (! projectName.equals("org.apache.felix.dependencymanager.benchmark")) {
    include projectName
    def project = getBndProject(workspace, projectName)
    project?.dependson.each {
      include it.name
    }
  }
}

/* Get the bnd project for the specified project name */
def getBndProject(Workspace workspace, String projectName) {
  def project = workspace.getProject(projectName)
  if (project == null) {
    return null
  }
  project.prepare()
  if (project.isValid()) {
    return project
  }

  project.getInfo(workspace, "${rootDir} :")
  def errorCount = 0
  project.warnings.each {
    println "Warning: ${it}"
  }
  project.errors.each {
    println "Error  : ${it}"
    errorCount++
  }
  if (!project.isOk()) {
    def str = 'even though no errors were reported'
    if (errorCount == 1) {
      str = 'one error was reported'
    } else if (errorCount > 1) {
      str = "${errorCount} errors were reported"
    }
    throw new GradleException("Project ${rootDir}/${projectName} is invalid, ${str}")
  }
  throw new GradleException("Project ${rootDir}/${projectName} is not a valid bnd project")
}

/* After the rootProject is created, set up some properties. */
gradle.rootProject { rootProject ->
  rootProject.ext.bndWorkspace = workspace
  rootProject.ext.cnf = rootProject.project(bnd_cnf)
}
