import groovy.json.JsonOutput
import groovy.json.JsonSlurper

import java.util.regex.Matcher
import java.util.regex.Pattern

plugins {
    id 'distribution'
    id 'maven-publish'
}

apply from: 'properties.gradle'

version = '5.1.1'
group = 'org.citydb'

tasks.register('versionFile') {
    outputs.dir "$projectDir/build/version"
    doLast {
        mkdir "$projectDir/build/version"
        file("$projectDir/build/version/version.txt").text = version
    }
}

tasks.register('bundleMavenZip', Zip) {
    group = distZip.group
    archiveFileName = "${project.name}-${project.version}.zip"
    destinationDirectory = file("$projectDir/build/maven")
    from installDist
}

distributions.main.contents {
    def featureTypes = readJsonTypes('schema-mapping/feature-types')
    def dataTypes = readJsonTypes('schema-mapping/data-types')
    def version = parseVersion("$project.version")
    filteringCharset = 'UTF-8'

    from 'LICENSE'
    from 'README.md'
    from versionFile
    into('json-schema') {
        from 'json-schema'
        filesMatching('**/*.json') {
            filter { String line -> replaceTokens(line, version, '', '') }
        }
    }
    into('postgresql') {
        from 'postgresql' exclude('db-schema')
        filesMatching('**/datatype-instances.sql') {
            filter { String line -> replaceTokens(line, dataTypes) }
        }
        filesMatching('**/objectclass-instances.sql') {
            filter { String line -> replaceTokens(line, featureTypes) }
        }
        filesMatching(['**/upgrade-db.sql', '**/util.sql']) {
            filter { String line -> replaceTokens(line, version, '', '') }
        }
    }
}

def readJsonTypes(String path) {
    def types = [:]
    def parser = new JsonSlurper()
    fileTree(path).matching { include "**/*.json" }
            .each { File file ->
                {
                    def type = parser.parse(file, "UTF-8")
                    if (type in Map) {
                        types[type.identifier] = JsonOutput.toJson(type)
                    }
                }
            }
    types
}

static def parseVersion(String versionString) {
    def version = [:]
    Matcher matcher = Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+).*?").matcher(versionString)
    if (matcher.matches()) {
        version["majorVersion"] = matcher.group(1)
        version["minorVersion"] = matcher.group(2)
        version["minorRevision"] = matcher.group(3)
        version["versionString"] = versionString
    } else {
        throw new GradleException("Failed to parse the version '$versionString'. Use SemVer notation.")
    }
    version
}

static def replaceTokens(
        String text, Map values,
        String beginReplacement = "'", String endReplacement = "'",
        String defaultValue = 'null',
        String beginToken = '@', String endToken = '@') {
    Pattern.compile(beginToken + "(.*?)" + endToken, Pattern.MULTILINE)
            .matcher(text)
            .replaceAll(matcher -> values[matcher.group(1)] ?
                    Matcher.quoteReplacement(beginReplacement + values[matcher.group(1)] + endReplacement) :
                    defaultValue)
}

artifacts {
    bundleMavenZip
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            artifact bundleMavenZip
            pom {
                name = project.name
                url = githubUrl
                scm {
                    url = githubUrl
                    connection = 'scm:git:' + gitConnection
                }
            }
        }
    }
    repositories {
        maven {
            url = project.hasProperty('gitLab_maven_url') ?
                    project.property('gitLab_maven_url') :
                    System.getenv('GITLAB_MAVEN_URL')
            name = 'gitlab-maven'
            credentials(HttpHeaderCredentials) {
                name = 'Private-Token'
                value = project.hasProperty('gitLab_private_token') ?
                        project.property('gitLab_private_token') :
                        System.getenv('GITLAB_PRIVATE_TOKEN')
            }
            authentication {
                header(HttpHeaderAuthentication)
            }
        }
    }
}