plugins {
    id "org.implab.gradle-typescript"
    id "org.implab.gradle-npm-package"
    id "ivy-publish"
}

typescript {
    useTsc npm.bin("tsc")

    compilerOptions {
        incremental = true
    }

    jsVariants {
        node {
            jsRuntime = "node"
            jsModule = "commonjs"
        }
        browser {
            jsRuntime = "browser"
            jsModule = "amd"
        }
    }
}

def typingsFromMain = {
    sets {
        named("compileOnlyTypings") {
            srcDir main.output("typings")
        }
    }
}

variants {
    all {

    }
}

// варианты сборки
variants {
    configureEach { variant ->
        // для каждого варианта есть стандартные настройки
        def sourceSetLocation = { setName, self ->
            self.sourceSetDir = layout.projectDirectory.dir("src/${setName}")
            self.outputsDir = layout.buildDirectory.dir("${variant.name}/${setName}")
        }

        def main = sources.register("${variant.name}Main", sourceSetLocation.curry("main"))
        def test = sources.register("${variant.name}Test", sourceSetLocation.curry("test"))

        // явно добавляем наборы в вариант для применения политик и агрегации результатов
        sourceSets {
            add(main, role: "main")
            add(test, role: "test")
        }
    }
    register("browser") {
        // специфичные наборы для варианта
        def srcMainAmd = sources.register("mainAmd", typingsFromMain)
        def srcTestAmd = sources.register("testAmd", typingsFromMain)

        // применение аспекта компиляции ts для данного варианта
        // advice to all TypescriptCompile tasks
        typescriptCompile {
            baseTsConfig = file("src/tsconfig.browser.json")
        }

        sourceSets {
            add(srcMainAmd, role: "main")
            add(srcTestAmd, role: "test")
        }
    }
    register("node") {
        // специфичные наборы для варианта
        def srcMainCjs = sources.register("mainCjs", typingsFromMain)
        def srcTestCjs = sources.register("testCjs", typingsFromMain)

        // применение аспекта компиляции ts для данного варианта
        typescriptCompile {
            baseTsConfig = file("src/tsconfig.node.json")
        }

        sourceSets {
            add(srcMainCjs, role: "main")
            add(srcTestCjs, role: "test")
        }
    }
}

npmPackaging {
    usePackageJson()
    metadata {
        name = "@implab/core"
        version = project.provider { project.version.toString() }
    }

    // creates writeBrowserPackageJson npmPackBrowser, npmPublishBrowser
    variant("browser") {
        metadata {
            name = "@implab/core-amd"
        }
        variantOutputs("main")
    }
    // creates writeNodePackageJson, npmPackNode, npmPublishNode
    variant("node") {
        metadata {
            name = "@implab/core-node"
        }
        variantOutputs("main")
    }

    // creates writePackageJson, npmPack, npmPublish
    package {
        metadata {
            name = "@implab/core-amd"
        }
        content { // CopySpec
            // как-то кривенько
            from(variants.named("node").map { it.outputs("main") }) {
                into "dist/node"
            }
            from(variants.named("browser").map { it.outputs("main") }) {
                into "dist/node"
            }
        }
    }
}

outgoingJs {

}

outgoingVariants {
    // registers nodeElements configuration
    variant("node") { // ConfigurationPublications
        // как-то шумно
        attribute(JS_RUNTIME, "node")
        attribute(JS_MODULE, "commonjs")
        attribute(JS_TARGET, "es2020")
        attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements, "npm-module"))

        // основной артефакт, связь по имени задачи, неудачный вариант
        artifact(tasks.named("npmPackNode"))

        // variants... кругом variants
        variants {
            exploded {
                attributes {
                    // шумновато, но это стандартное API gradle
                    attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements, "exploded-npm-module"))
                }
                // связь по имени задачи, неудачный вариант
                artifact(tasks.named("assembleNodeModule"))
            }
            typings {
                attributes {
                    attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements, "typescript-typings"))
                }
                // связь по имени задачи, неудачный вариант
                artifact(tasks.named("assembleNode"))
            }
        }
    }
    variant("browser") {
        // все те же проблемы что и для variant("node")

        attribute(JS_RUNTIME, "browser")
        attribute(JS_MODULE, "amd")
        attribute(JS_TARGET, "es2015")
        attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements, "npm-module"))
        artifact(tasks.named("npmPackBrowser"))

        variants {
            variants {
                typings {
                    attributes {
                        attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements, "typescript-typings"))
                    }
                    artifact(tasks.named("assembleNode"))
                }
            }
        }
    }
}

publishing {
    repositories {
        ivy {
            url "${System.properties["user.home"]}/ivy-repo"
        }
    }
    publications {
        ivy(IvyPublication) {
            from components.js
        }
    }
}