abstract class MixinTask extends DefaultTask {

    @Input
    abstract Property<String> getMixinRefMapName()

    private File mixinSrg
    private File mixinRefMap

    MixinTask() {
        mixinRefMapName.convention("mixin.${project.name.replaceAll('[_\\-.]', '').toLowerCase()}.refmap.json")
    }

    @TaskAction
    void action() {
        def mixinDir = new File(project.buildDir, 'mixins')
        if (!mixinDir.exists()) {
            mixinDir.mkdirs()
        }
        def srgFile = new File(project.buildDir, 'srgs/mcp-srg.srg')
        mixinSrg = new File(mixinDir, "${mixinRefMapName.get()}.srg")
        mixinRefMap = new File(mixinDir, mixinRefMapName.get())

        if (!mixinSrg.exists()) {
            mixinSrg.createNewFile()
        }

        project.tasks.reobf.configure {
            addExtraSrgFile mixinSrg
        }

        def compileJava = project.tasks.compileJava
        compileJava.configure {
            options.compilerArgs += [
                    '-Xlint:-processing',
                    "-AoutSrgFile=${mixinSrg.canonicalPath}",
                    "-AoutRefMapFile=${mixinRefMap.canonicalPath}",
                    "-AreobfSrgFile=${srgFile.canonicalPath}"
            ]
        }

        project.tasks.jar.configure {
            from mixinRefMap
        }
    }

    @Internal
    File getMixinSrg() {
        return mixinSrg
    }

    @Internal
    File getMixinRefMap() {
        return mixinRefMap
    }
}

tasks.register('mixin', MixinTask)

task copySrgs(type: Copy, dependsOn: 'genSrgs') {
    from plugins.getPlugin('forge').delayedFile('{SRG_DIR}')
    include '**/*.srg'
    into layout.buildDirectory.file('srgs')
}

compileJava.dependsOn(copySrgs, mixin)
tasks.findByPath(":prepareKotlinBuildScriptModel")?.dependsOn(copySrgs, mixin)

processResources {
    afterEvaluate {
        def refmap = tasks.mixin.mixinRefMapName.get()
        inputs.property 'mixin_refmap', refmap
        from(sourceSets.main.resources.srcDirs) {
            include '*.json'
            expand 'mixin_refmap': refmap
            duplicatesStrategy = DuplicatesStrategy.INCLUDE
        }
    }
}