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

buildscript {
    repositories {
        mavenCentral()
        jcenter()
    }

    dependencies {
        classpath "org.asciidoctor:asciidoctorj:1.6.2"
    }
}

plugins {
    id 'java'
    id 'com.github.jruby-gradle.base' version '2.0.0'
}

// This project does not contribute anything to main dependencies.
versionsLock {
    testProject()
}

description = 'Solr reference guide'

// Use an internal proxy to ruby gems.
repositories {
    ruby.gems()
}

configurations {
    depVer
    refGuide
}

dependencies {
    // Dependencies to compile internal tools.
    implementation('org.asciidoctor:asciidoctorj')
    implementation('com.vaadin.external.google:android-json')
    implementation('org.jsoup:jsoup')
    implementation('org.slf4j:jcl-over-slf4j')
    implementation('org.slf4j:slf4j-simple')
    implementation('org.apache.logging.log4j:log4j-core')
    implementation('com.google.guava:guava')
    implementation('commons-codec:commons-codec')

    // Dependencies referenced in the guide.
    depVer('commons-codec:commons-codec')
    depVer('io.dropwizard.metrics:metrics-core')
    depVer('org.apache.logging.log4j:log4j-core')
    depVer('org.apache.opennlp:opennlp-tools')
    depVer('org.apache.tika:tika-core')
    depVer('org.apache.zookeeper:zookeeper')

    // jekyll dependencies
    gems 'rubygems:jekyll:3.5.2'
    gems 'rubygems:jekyll-asciidoc:3.0.0'

    // don't know why we have to explicitly add these deps but it doesn't resolve them
    // automatically.
    gems 'rubygems:tilt:2.0.10'
    gems 'rubygems:slim:4.0.1'
    gems 'rubygems:concurrent-ruby:1.0.5'
}

sourceSets {
    refGuide {
        java {
            srcDirs = []
        }
        resources {
            srcDirs = ['src']
        }
    }

    main {
        java {
            srcDirs = ['tools']
        }
    }

    test {
        java {
            srcDirs = []
        }
    }
}

ext {
    mainPage = "index"

    // the "MAJOR.MINOR" version of solr this guide is about (guides aren't specific to BUGFIX releases)
    // So on 'branch_9_9' where 'version' may be 9.9.0, 9.9.1, 9.9.9, etc..;  solrDocsVersion = 9.9
    solrDocsVersion = "${version}".replaceAll(/^(\d+\.\d+)(|\..*)$/, "\$1")
    
    // the "MAJOR_MINOR" version as a path for publishing the guide
    // So on 'branch_9_9' where solrDocsVersion = 9.9; solrGuideVersionPath => 9_9
    solrGuideVersionPath = "${solrDocsVersion}".replaceAll(/^(\d+)\.(\d+)$/, "\$1_\$2")

    // these will be used to dynamically build up (nearly) identical tasks with consistent names
    // for building & link checking the ref guide.  One using absolute URLs to javadocs, the
    // other using local paths that can be validated by the link checker.
    htmlSiteDetails =
        [name: 'Site',
         path: 'html-site',
         desc: 'HTML Site for publishing to the Solr website',
         props: [
            htmlSolrJavadocs: "https://lucene.apache.org/solr/${solrGuideVersionPath}_0/",
            htmlLuceneJavadocs: "https://lucene.apache.org/core/${solrGuideVersionPath}_0/"
        ]
    ]
    linkCheckSiteDetails =
        [name: 'LocalJavadocLinksSite',
         path: 'local-jdoc-links-site',
         desc: 'Local Site for checking javadoc links',
         
         // NOTE: extra '../' because we'll in a sub-dir of buildDir that will be built later...
         props: [
            htmlSolrJavadocs : 'link:../' + buildDir.toPath().relativize(project(':solr:documentation').docroot.toPath()).toString().replace(File.separator, '/'),
            htmlLuceneJavadocs : 'link:../' + buildDir.toPath().relativize(project(':lucene:documentation').docroot.toPath()).toString().replace(File.separator, '/')
        ]
    ]
}

// dynamically define the 2 variations of each target that we need...
[ htmlSiteDetails, linkCheckSiteDetails ].each{ details ->
    final def contentDir = file("${buildDir}/${details.path}-content")
    final def htmlDir = file("${buildDir}/${details.path}")
    final def extraProps = details.props.clone()
    extraProps.htmlOutDir = "../${details.path}"
    
    task "prepare${details.name}Sources"(type: PrepareSources) {
        outDir contentDir
        props extraProps
    }
    
    task "build${details.name}"(type: com.github.jrubygradle.JRubyExec) {
        dependsOn "prepare${details.name}Sources"
        group "Documentation"
        description "Builds the ${details.desc}"

        inputs.dir contentDir
        outputs.dir htmlDir

        script 'jekyll'
        scriptArgs 'build' //, '--verbose'
        workingDir contentDir
    }

    task "check${details.name}"(type: JavaExec) {
        dependsOn "build${details.name}"

        classpath = sourceSets.main.runtimeClasspath
        main = 'CheckLinksAndAnchors'
        workingDir = contentDir

        // NOTE: even for the 'real' site, we check all relative links
        // (there will just be less of them, and this way any stray hardcoded
        // '../../' paths can be caught more easily)
        args([ htmlDir, "-check-all-relative-links" ])
    }
}

// Hook in our dependency on all top level documentation in order to check local javadoc links
checkLocalJavadocLinksSite.dependsOn ':documentation'

// Hook up custom tasks with standard tasks. 
check.dependsOn checkLocalJavadocLinksSite, checkSite

// Hook site building to assemble.
assemble.dependsOn buildSite 

abstract class PrepareSources extends DefaultTask {
    
    /** Original Source files we'll be syncing <b>FROM</b> */
    @InputDirectory
    public File getSrcDir() {
        return getProject().file("src")
    }

    /** 
     * Where we sync the source files <b>TO</b>
     */
    public void setOutDir(File outDir) {
        this.outDir = outDir;
        getOutputs().dir(outDir);
    }
    public File outDir;

    /**
     * Task specific props
     */
    @Input
    public Map<String,String> getProps() {
        return props;
    }
    public void setProps(Map<String,String> props) {
        this.props = props;
    }
    private Map<String,String> props;

    /**
     * Basic properties that should be the same for all tasks of this type
     */
    @Input
    public Map<String,String> getStandardProps() {
        final Project p = getProject();
        return [
            javadocLink : "https://docs.oracle.com/en/java/javase/11/docs/api/",
            solrGuideDraftStatus : p.propertyOrDefault('solrGuideDraft', "true").toBoolean() ? "DRAFT" : "",
            solrRootPath : p.project(':solr').projectDir.toString() + File.separator,
            solrDocsVersion : p.property('solrDocsVersion'),
            solrGuideVersionPath : p.property('solrGuideVersionPath'),
            buildDate : p.property('buildDate'),
            buildYear : p.property('buildYear'),
        ];
    }

    public PrepareSources() {
        // setup 'dependsOn classes, configurations.depVer' here
        // so that it's not neccessary for every task impl to declare redundently
        final Project p = getProject();
        dependsOn(p.getConfigurations().getByName('depVer'))
        dependsOn(p.getTasksByName('classes', false))
        
    }

    @TaskAction
    public void doCopy() {
        final Project p = getProject();
        final Configuration depVer = p.getConfigurations().getByName('depVer');
        
        // start with any task (instance) specific props.
        final def props = getProps().clone();
        // then add/override with anystandard props that should alwasy be used
        getStandardProps().each { k, v -> props[k] = v };
        
        // These properties have to be resolved after the configuration phase is complete
        // (palantir's constraint) so we can't use them as input for caches. But as this task
        // depends on the configuration, it's used correctly
        [
            ["ivyCommonsCodec", "commons-codec", "commons-codec"],
            ["ivyDropwizardMetrics", "io.dropwizard.metrics", "metrics-core"],
            ["ivyLog4j", "org.apache.logging.log4j", "log4j-core"],
            ["ivyOpennlpTools", "org.apache.opennlp", "opennlp-tools"],
            ["ivyTika", "org.apache.tika", "tika-core"],
            ["ivyZookeeper", "org.apache.zookeeper", "zookeeper"],
        ].each { prop, depGroup, depId ->
            props[prop] = p.getVersion(depGroup, depId, depVer)
        }
        
        final File intoDir = this.outDir;
        
        // Emit info about properties for clarity.
        logger.lifecycle('Syncing source files to {} using props:\n{}',
                         intoDir, props.collect({ k, v -> "  ${k} -> ${v}" }).join('\n'))
        
        // Escape all the properties, so they can be inserted into YAML templates.
        final def escapedProps = props.collectEntries{k, v -> [k, v.replace("'","''")]}
        
        final WorkResult syncResult = p.sync({ copySpec ->
            copySpec.setFilteringCharset('UTF-8');
            copySpec.from(getSrcDir(), { raw -> 
                raw.exclude('**/*.template')
            })
            
            copySpec.from(getSrcDir(), { templated ->
                templated.include('**/*.template')
                templated.rename('(.+)\\.template', '$1')
                templated.expand(escapedProps)
            })
            copySpec.into(intoDir);
        });
        setDidWork(syncResult.getDidWork());
        if (syncResult.getDidWork()) {
            // if sync did work, that means we need to rebuild the nav data files...
            p.javaexec({ execSpec ->
                execSpec.setClasspath( getProject().getConvention()
                                      .getPlugin(JavaPluginConvention.class)
                                      .getSourceSets().getByName("main").getRuntimeClasspath() )
                execSpec.setWorkingDir( intoDir )
                execSpec.setMain( 'BuildNavDataFiles' )
                execSpec.args([ intoDir, p.property('mainPage') ])
            })
        }
    }
}
