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

def resources = scriptResources(buildscript)

configure(subprojects.findAll { it.path == ':lucene:documentation' || it.path == ':solr:documentation' }) {
  task changesToHtml(type: ChangesToHtmlTask) {
    siteDir = resources
    script = file("${resources}/changes2html.pl")
  }
}

// compile changes.txt into an html file
class ChangesToHtmlTask extends DefaultTask {

  @Internal
  Project productProject = project.parent

  @Internal
  String productName = productProject.name

  @InputFile
  File changesFile = productProject.file('CHANGES.txt')

  @InputFile
  File changesDoapFile = project.rootProject.file("dev-tools/doap/${productName}.rdf")

  @InputDirectory
  File siteDir

  @OutputDirectory
  final DirectoryProperty targetDir = project.objects.directoryProperty()
    .fileProvider(project.providers.provider { project.file("${project.docroot}/changes") })

  @Input
  def luceneDocUrl = "${->project.luceneDocUrl}"

  @InputFile
  def script

  def loadVersions(File outfile) {
    // load version properties from DOAP RDF
    def prefix = "doap.${productName}".toString()
    ant.xmlproperty(keeproot: false, file: changesDoapFile, collapseAttributes: false, prefix: "${prefix}")
    outfile.withWriter("UTF-8") { writer ->
      writer.println(ant.properties["${prefix}.Project.release.Version.revision"])
      writer.println(ant.properties["${prefix}.Project.release.Version.created"])
    }
  }

  def toHtml(File versionsFile) {
    def output = new ByteArrayOutputStream()
    def result = project.exec {
      executable project.externalTool("perl")
      standardInput changesFile.newInputStream()
      standardOutput project.file("${targetDir.get().getAsFile()}/Changes.html").newOutputStream()
      errorOutput = output
      ignoreExitValue = true

      args += [
        "-CSD",
        script,
        "${productName}",
        versionsFile.toString(),
        luceneDocUrl.concat('/')   // slash required at end by perl script
      ]
    }

    if (result.getExitValue() != 0) {
      throw new GradleException("Changes generation failed:\n${output}")
    }
  }

  @TaskAction
  def convert() {
    project.mkdir targetDir
    if (changesFile.exists() && changesDoapFile.exists()) {
      File versionsFile = project.file("${project.buildDir}/doap.${project.name}.changes.version.dates.csv")
      loadVersions(versionsFile)
      toHtml(versionsFile)
      project.copy {
        from siteDir
        into targetDir
        include "*.css"
      }
      versionsFile.delete()
    } else {
      throw new GradleException("Changes file ${changesFile} or Doap file ${changesDoapFile} not found.")
    }
  }
}
