import org.gradle.api.artifacts.DependencyResolveDetails
import java.util.zip.GZIPOutputStream
apply from: "build-version.gradle"
// 判断项目是否是普通前端项目
def isFrontendProject(currentDir){
    return file(currentDir.getAbsolutePath() + '/package.json').exists()
            && !file(currentDir.getAbsolutePath() + '/webpack.env.lib.cjs').exists();
}
/***********************************************************************
 * gradle 插件
 **********************************************************************/
buildscript {
    repositories {
        maven {
            allowInsecureProtocol = true
            url "${repository_url}"
        }
    }
    dependencies {
        classpath "com.gradleup.shadow:shadow-gradle-plugin:${shadow_gradle_plugin_version}"
        classpath "org.springframework.boot:org.springframework.boot.gradle.plugin:${spring_boot_version}"
        //classpath "io.sc:io.sc.platform.gradle:${platform_plugin_version}"
        classpath "org.asciidoctor:asciidoctor-gradle-jvm:${asciidoctor_version}"
        classpath "com.google.cloud.tools:jib-gradle-plugin:${jib_version}"
    }
}
/***********************************************************************
 * 所有项目(根项目及其子项目)都应用的插件
 **********************************************************************/
allprojects {
    apply plugin: 'idea'
    //apply plugin: 'io.sc.platform.gradle'
}
/***********************************************************************
 * 所有子项目应用的插件
 **********************************************************************/
subprojects {
    apply plugin: 'java'
    apply plugin: 'java-library'
    apply plugin: 'eclipse'
    apply plugin: 'maven-publish'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: 'org.asciidoctor.jvm.convert'
	configurations.all {
	    //设置 gradle 拉取依赖包的缓存策略为不进行缓存,可保证每次拉取最新的依赖包
	    //resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'     //动态版本: 1.1.+
	    //resolutionStrategy.cacheChangingModulesFor 0, 'seconds'     //静态版本: 1.1.2
        //排除不需要的外部依赖
//	    exclude group: "org.apache.logging.log4j",  module: "log4j-api"
//      exclude group: "org.apache.logging.log4j",  module: "log4j-to-slf4j"
//      exclude group: "org.slf4j",                 module: "slf4j-jdk14"
        exclude group: "org.slf4j",                 module: "slf4j-nop"
        //exclude group: "com.mysql",                 module: "mysql-connector-j"
        if(PlatformDependencyVersions!=null && PlatformDependencyVersions.size()>0) {
            resolutionStrategy.eachDependency { DependencyResolveDetails detail ->
                def requested = detail.requested;
                def groupAndName = requested.group + ":" + requested.name;
                String version = PlatformDependencyVersions[groupAndName];
                if (version != null) {
                    detail.useVersion(version);
                }
            }
        }
	}
	dependencyManagement {
	    resolutionStrategy {
	        //设置 gradle 拉取依赖包的缓存策略为不进行缓存,可保证每次拉取最新的依赖包
	        //cacheDynamicVersionsFor 0, 'seconds'                    //动态版本: 1.1.+
            //cacheChangingModulesFor 0, 'seconds'                    //静态版本: 1.1.2
        }
		imports {
			//mavenBom "org.springframework.cloud:spring-cloud-dependencies:${spring_cloud_version}"
            mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:${spring_cloud_alibaba_version}"
            mavenBom "org.springframework.statemachine:spring-statemachine-bom:${spring_statemachine_version}"
		}
	}
	/*-----------------------------------------------------------------
     * 配置构建时所需依赖的仓库 url
     * 将仓库 url 都定位到 ${repository_url} 指定的本地私有仓库地址
     *----------------------------------------------------------------*/
	repositories {
		all { ArtifactRepository repo ->
            if(repo instanceof MavenArtifactRepository){
                def url = repo.url.toString()
                if (
                	   url.startsWith('https://repo1.maven.org/maven2')
                	|| url.startsWith('https://jcenter.bintray.com/')
                	|| url.startsWith('https://maven.aliyun.com')
                ) {
                    remove repo
                }
            }
        }
		maven {
			allowInsecureProtocol = true
			url "${repository_url}"
		}
	}
	/*-----------------------------------------------------------------
     * java 编译时选项
     *----------------------------------------------------------------*/
    sourceCompatibility ="${java_version}"
	targetCompatibility ="${java_version}"
	compileJava.options.encoding ="${java_encoding}"
	compileTestJava.options.encoding ="${java_encoding}"
	tasks.withType(JavaCompile) {
    	options.compilerArgs += ["-Xlint:deprecation","-Xlint:unchecked"]
	}
	/*-----------------------------------------------------------------
     * 配置项目基本信息
     *----------------------------------------------------------------*/
	group ="${platform_group}"
	version ="${platform_version}"
    if(file('package.json').exists()){
        mkdir 'java-src/main/java';
        mkdir 'java-src/main/resources';
        mkdir 'dist';
        sourceSets.main.java.srcDir 'java-src/main/java'
        sourceSets.main.resources.srcDir 'java-src/main/resources'
    	sourceSets.main.resources.srcDir 'dist'
    }
    /*-----------------------------------------------------------------
     * 源代码打包配置
     *----------------------------------------------------------------*/
    task sourcesJar (type : Jar) {
        from sourceSets.main.allJava
        archiveClassifier = 'sources'
    }
    /*-----------------------------------------------------------------
     * Java 文档打包配置
     *----------------------------------------------------------------*/
    javadoc {
        options.encoding = 'UTF-8'
        // 为了能够尽量规范 java doc 文档编写, 指定如果 java doc 中有错误,会报错,并且无法发布到仓库中
        failOnError=false
    }
    task javadocJar (type: Jar) {
        from javadoc
        archiveClassifier = 'javadoc'
    }
    clean {
        delete 'bin'										//删除 eclipse 编译的 bin 目录
        delete 'build'										//删除 gradle 构建目录
        delete 'dist'                                       //删除前端打包后的目录
        delete 'node_modules'                               //删除前端 node_modules 目录
        delete 'pnpm-lock.yaml'                             //删除前端 pnpm 文件
        delete 'package-lock.json'                          //删除前端 npm 文件
    }
	/*-----------------------------------------------------------------
     * 配置 eclipse 插件
     *----------------------------------------------------------------*/
    eclipse{
		jdt{
			sourceCompatibility ="${java_version}"
			targetCompatibility ="${java_version}"
		}
	}
	/*-----------------------------------------------------------------
     * springboot 插件配置
     *----------------------------------------------------------------*/
    jar {
    	//可以生成普通的 jar
		enabled = true
		archiveClassifier.set("")
		manifest {
            attributes 	'Manifest-Version'		: '1.0',
                        'Implementation-Title'	: name,
                        'Implementation-Vendor'	: group,
                        'Implementation-Version': archiveVersion
        }
    }
	/*-----------------------------------------------------------------
     * asciidoctor 插件配置,用于生成 asciidoc 文档,用于打包到 jar 中
     *----------------------------------------------------------------*/
	asciidoctor {
		baseDirFollowsSourceDir()
		outputs.upToDateWhen { true }
		logDocuments = true
    	sourceDir = file('asciidoc')
    	sources {
    		include '*.adoc'
    	}
        outputDir = file("dist/help/" + project.name)
        resources {
            from(sourceDir) {
                include 'resources/**'
            }
        }
    }
    asciidoctorj {
	    modules {
	       diagram.use()
	    }
	}
    /*-----------------------------------------------------------------
     * 自定义任务,用于生成 asciidoc 文档到 web 服务器,以便实时查看效果
     *----------------------------------------------------------------*/
    task doc(type: org.asciidoctor.gradle.jvm.AsciidoctorTask){
    	baseDirFollowsSourceDir()
		outputs.upToDateWhen { true }
		logDocuments = true
    	sourceDir = file('asciidoc')
    	sources {
    		include '*.adoc'
    	}
    	outputDir = file("$asciidoc_deploy_dir" + project.name)
        // 拷贝 asciidoc 自定义资源
        // 设置方式: 通过命令行 -D 传入目标环境参数
        // gradle doc -DdocResource=true     # 需要拷贝自定义资源
        // gradle doc -DdocResource=false    # 不需要拷贝自定义资源
        def docResource =System.getProperty("docResource")?:"true";
        if(docResource=="true"){
            resources {
                from(sourceDir) {
                    include 'resources/**'
                }
            }
        }
	}
    /*-----------------------------------------------------------------
     * 资源处理前执行 asciidoctor
     *----------------------------------------------------------------*/
    processResources {
    	dependsOn asciidoctor
    	doLast{
    		//打包时移除 jrebel 相关的文件
    		delete "$buildDir/resources/main/rebel.xml"
    	}
	}
    /*-----------------------------------------------------------------
     * 用于自动生成 jrebel.xml 文件的自定义任务(eclipse)
     *----------------------------------------------------------------*/
	task jrebelEclipse() {}
	tasks.jrebelEclipse.doLast {
		File resourcesFile =file('src/main/resources')
		if(resourcesFile!=null && resourcesFile.exists()){
			File rebelFile = file('src/main/resources/rebel.xml')
			rebelFile.withWriter('UTF-8') { writer ->
				writer.write('\n');
				writer.write('\n');
				writer.write('\t\n');
				if(file(project.name + '/src/main').exists()){
					writer.write('\t\t\n');
				}
				if(file(project.name + '/src/generated').exists()){
					writer.write('\t\t\n');
				}
				writer.write('\t\n');
				writer.write('');
			}
		}
	}
    /*-----------------------------------------------------------------
     * 用于自动生成 jrebel.xml 文件的自定义任务(idea)
     *----------------------------------------------------------------*/
	task jrebelIdea() {}
	tasks.jrebelIdea.doLast {
        if(isFrontendProject(file('.'))) {
            File resourcesFile = file('java-src/main/resources')
            if (resourcesFile != null && resourcesFile.exists()) {
                File rebelFile = file('java-src/main/resources/rebel.xml')
                rebelFile.withWriter('UTF-8') { writer ->
                    writer.write('\n');
                    writer.write('\n');
                    writer.write('\t\n');
                    if (file(project.name + '/java-src/main').exists()) {
                        writer.write('\t\t\n');
                    }
                    writer.write('\t\n');
                    writer.write('');
                }
            }
        }else {
            File resourcesFile = file('src/main/resources')
            if (resourcesFile != null && resourcesFile.exists()) {
                File rebelFile = file('src/main/resources/rebel.xml')
                rebelFile.withWriter('UTF-8') { writer ->
                    writer.write('\n');
                    writer.write('\n');
                    writer.write('\t\n');
                    if (file(project.name + '/src/main').exists()) {
                        writer.write('\t\t\n');
                    }
                    writer.write('\t\n');
                    writer.write('');
                }
            }
        }
	}
    /*-----------------------------------------------------------------
     * maven publish 插件配置
     *----------------------------------------------------------------*/
    publishing {
        repositories {
            maven {
            	allowInsecureProtocol = true        //允许采用 http 协议发布
                url = version.contains('SNAPSHOT') ? "${repository_snapshot_url}" : "${repository_release_url}"
                credentials {
                    username = (version.contains('SNAPSHOT') ? "${repository_snapshot_username}" : "${repository_release_username}")
                    password = (version.contains('SNAPSHOT') ? "${repository_snapshot_password}" : "${repository_release_password}")
				}
            }
        }
        publications{
            publication(MavenPublication){
                from components.java
                //artifact sourcesJar
                //artifact javadocJar
                versionMapping {
	                usage('java-api') {
	                    fromResolutionOf('runtimeClasspath')
	                }
	                usage('java-runtime') {
	                    fromResolutionResult()
	                }
	            }
            }
        }
    }
	/*-----------------------------------------------------------------
     * 更新前端模块的 package.json 文件,同步其中的 name 和 version
     *----------------------------------------------------------------*/
    task frontendUpdatePackageJson(){}
    tasks.frontendUpdatePackageJson.doFirst {
        if(isFrontendProject(file('.'))) {
            println '开始执行 frontendUpdatePackageJson ......'
        }
    }
    tasks.frontendUpdatePackageJson.doLast {
        if(isFrontendProject(file('.'))){
            String content =file('package.json').text;
            def packageJson = new groovy.json.JsonSlurper().parseText(content);
            if(packageJson!=null){
                println packageJson.dependencies;
                packageJson.name =project.name;
                packageJson.version =project.version;
                packageJson.dependencies['platform-core']=platform_core_frontend_version;
                def json = groovy.json.JsonOutput.toJson(packageJson);
                file('package.json').withWriter('UTF-8') { writer ->
                    writer.write(groovy.json.JsonOutput.prettyPrint(json));
                }
            }
        }
    }
	/*-----------------------------------------------------------------
     * pnpm install
     *----------------------------------------------------------------*/
    task frontendNpmInstall(type:Exec){
        if(isFrontendProject(file('.'))){
            workingDir '.'
            if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
                commandLine 'cmd', '/c', 'pnpm', 'install'
            }else{
                commandLine 'pnpm', 'install'
            }
        }else{
            if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
                commandLine 'cmd', '/c', 'cd', '.'
            }else{
                commandLine 'cd', '.'
            }
        }
    }
    tasks.frontendNpmInstall.doFirst {
        if(isFrontendProject(file('.'))) {
            println '开始执行 pnpm install ......';
        }
    }
    /*-----------------------------------------------------------------
     * pnpm sync
     *----------------------------------------------------------------*/
    task frontendNpmSync(type:Exec){
        if(isFrontendProject(file('.')) && !project.name.contains("io.sc.platform.security.frontend")){
            workingDir '.'
            if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
                commandLine 'cmd', '/c', 'pnpm', 'sync'
            }else{
                commandLine 'pnpm', 'sync'
            }
        }else{
            if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
                commandLine 'cmd', '/c', 'cd', '.'
            }else{
                commandLine 'cd', '.'
            }
        }
    }
    tasks.frontendNpmSync.doFirst {
        if(isFrontendProject(file('.'))) {
            println '开始执行 pnpm sync ......';
        }
    }
    /*-----------------------------------------------------------------
     * pnpm re install
     *----------------------------------------------------------------*/
    task frontendNpmReInstall(type:Exec){
        if(isFrontendProject(file('.'))){
            workingDir '.'
            if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
                commandLine 'cmd', '/c', 'pnpm', 'install'
            }else{
                commandLine 'pnpm', 'install'
            }
        }else{
            if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
                commandLine 'cmd', '/c', 'cd', '.'
            }else{
                commandLine 'cd', '.'
            }
        }
    }
    tasks.frontendNpmReInstall.doFirst {
        if(isFrontendProject(file('.'))) {
            println '开始执行 pnpm re install ......';
        }
    }
	/*-----------------------------------------------------------------
     * pnpm run build
     *----------------------------------------------------------------*/
    task frontendNpmBuild(type:Exec) {
        if(isFrontendProject(file('.'))){
            workingDir '.'
            if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
                commandLine 'cmd', '/c', 'pnpm', 'run', 'build'
            }else{
                commandLine 'pnpm', 'run', 'build'
            }
        }else{
            if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
                commandLine 'cmd', '/c', 'cd', '.'
            }else{
                commandLine 'cd', '.'
            }
        }
    }
    tasks.frontendNpmBuild.doFirst {
        if (isFrontendProject(file('.'))) {
            println '开始执行 pnpm run build ......'
        }
    }
	/*-----------------------------------------------------------------
     * pnpm run prod
     *----------------------------------------------------------------*/
    task frontendNpmProd(type:Exec) {
        if(isFrontendProject(file('.'))){
            workingDir '.'
            if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
                commandLine 'cmd', '/c', 'pnpm', 'run', 'prod'
            }else{
                commandLine 'pnpm', 'run', 'prod'
            }
        }else{
            if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
                commandLine 'cmd', '/c', 'cd', '.'
            }else{
                commandLine 'cd', '.'
            }
        }
    }
    tasks.frontendNpmProd.doFirst {
        if(isFrontendProject(file('.'))){
            println '开始执行 pnpm run prod ......'
        }
    }
    /*-----------------------------------------------------------------
     * 将入口前端 dist/public/模块名 目录下 index.html 文件复制到 classpath:/templates/模块名.html
     * 提供给 thymeleaf 作为视图模板使用
     *----------------------------------------------------------------*/
    task frontendGenerateThymeleafTemplate {}
    tasks.frontendGenerateThymeleafTemplate.doFirst {
        if(isFrontendProject(file('.'))) {
            println '开始执行 frontendGenerateThymeleafTemplate ......'
            delete "java-src/main/resources/templates"
            mkdir "java-src/main/resources/templates"
        }
    }
    tasks.frontendGenerateThymeleafTemplate.doLast {
        if(isFrontendProject(file('.'))) {
            if(!file("dist/public/${project.name}/index.html").exists()){
                return;
            }
            def content = file("dist/public/${project.name}/index.html").text;
            content = content.replace('