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

package freemarker.build

import java.io.File
import java.nio.charset.StandardCharsets
import java.nio.file.FileVisitResult
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.SimpleFileVisitor
import java.nio.file.attribute.BasicFileAttributes
import java.util.TreeSet
import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.file.EmptyFileVisitor
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.FileVisitDetails
import org.gradle.api.file.ProjectLayout
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.IgnoreEmptyDirectories
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.SkipWhenEmpty
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.property
import org.gradle.kotlin.dsl.setProperty
import org.gradle.kotlin.dsl.submit
import org.gradle.process.ExecOperations
import org.gradle.workers.WorkAction
import org.gradle.workers.WorkParameters
import org.gradle.workers.WorkerExecutor

private const val JAVACC_MAIN_CLASS = "org.javacc.parser.Main"

data class JavaccReplacePattern(val relPath: String, val pattern: String, val replacement: String) : java.io.Serializable

open class CompileJavaccTask @Inject constructor(
    private val fs: FileSystemOperations,
    private val execOps: ExecOperations,
    private val exec: WorkerExecutor,
    layout: ProjectLayout,
    objects: ObjectFactory
) : DefaultTask() {

    @InputDirectory
    @SkipWhenEmpty
    @IgnoreEmptyDirectories
    @PathSensitive(PathSensitivity.RELATIVE)
    val sourceDirectory = objects.directoryProperty().value(layout.projectDirectory.dir("src/main/javacc"))

    @Input
    val javaccVersion = objects.property<String>().value("7.0.12")

    private val javaccClasspath = objects.fileCollection().apply {
        val dependencies = project.dependencies
        val configurations = project.configurations

        from(javaccVersion.map { versionValue ->
            dependencies
                .create("net.java.dev.javacc:javacc:${versionValue}")
                .let { configurations.detachedConfiguration(it) }
        })
    }

    @Input
    val fileNameOverrides = objects.setProperty<String>()

    @Input
    val replacePatterns = objects.setProperty<JavaccReplacePattern>()

    @OutputDirectory
    val destinationDirectory = objects.directoryProperty().value(layout.buildDirectory.dir("generated/javacc"))

    fun replacePattern(relPath: String, pattern: String, replacement: String) {
        replacePatterns.add(JavaccReplacePattern(relPath, pattern, replacement))
    }

    private fun hasJavaccOnClasspath(): Boolean {
        try {
            Class.forName(JAVACC_MAIN_CLASS)
            return true
        } catch (ex: ClassNotFoundException) {
            return false
        }
    }

    @TaskAction
    fun compileFiles() {
        fs.delete { delete(destinationDirectory) }

        val destRoot = destinationDirectory.get().asFile

        compileFiles(destRoot)
        deleteOverriddenFiles(destRoot)
        updateFiles(destRoot)
    }

    private fun compileFiles(destRoot: File) {
        withJavaccRunner {
            sourceDirectory.asFileTree.visit(object : EmptyFileVisitor() {
                override fun visitFile(fileDetails: FileVisitDetails) {
                    val outputDir = fileDetails.relativePath.parent.getFile(destRoot)
                    Files.createDirectories(outputDir.toPath())

                    runJavacc(listOf(
                        "-OUTPUT_DIRECTORY=$outputDir",
                        fileDetails.file.toString()
                    ))
                }
            })
        }
    }

    private fun deleteOverriddenFiles(destRoot: File) {
        val fileNameOverridesSnapshot = fileNameOverrides.get()
        val deletedFileNames = HashSet<String>()

        Files.walkFileTree(destRoot.toPath(), object : SimpleFileVisitor<Path>() {
            override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
                val fileName = file.fileName.toString()
                if (fileNameOverridesSnapshot.contains(fileName)) {
                    deletedFileNames.add(fileName)
                    Files.delete(file)
                }
                return FileVisitResult.CONTINUE
            }
        })

        val unusedFileNames = TreeSet(fileNameOverridesSnapshot)
        unusedFileNames.removeAll(deletedFileNames)
        if (unusedFileNames.isNotEmpty()) {
            logger.warn("Javacc did not generate the following files," +
                    " even though they are marked as overridden: $unusedFileNames")
        }
    }

    private fun updateFiles(destRoot: File) {
        replacePatterns.get().groupBy { it.relPath }.forEach { (relPath, patternDefs) ->
            val file = destRoot.toPath().resolve(relPath.replace("/", File.separator))

            val encoding = StandardCharsets.ISO_8859_1
            val origContent = String(Files.readAllBytes(file), encoding)
            var adjContent = origContent
            for (patternDef in patternDefs) {
                val prevContent = adjContent
                adjContent = adjContent.replace(patternDef.pattern, patternDef.replacement)
                if (prevContent == adjContent) {
                    logger.warn("$file was not modified, because it does not contain the requested token: '${patternDef.pattern}'")
                }
            }

            if (origContent != adjContent) {
                Files.write(file, adjContent.toByteArray(encoding))
            }
        }
    }

    private fun withJavaccRunner(action: JavaccRunner.() -> Unit) {
        if (hasJavaccOnClasspath()) {
            logger.warn("Found Javacc (${JAVACC_MAIN_CLASS}) on classpath. Switching to process isolation," +
                    " because Javacc relies on static fields. Consider removing Javacc from the classpath" +
                    " to improve performance."
            )
            withProcessJavaccRunner(action)
        } else {
            withClasspathJavaccRunner(action)
        }
    }

    private fun withProcessJavaccRunner(action: JavaccRunner.() -> Unit) {
        action { actionArgs ->
            val execResult = execOps.javaexec {
                classpath = javaccClasspath
                mainClass.set(JAVACC_MAIN_CLASS)
                args = actionArgs
                isIgnoreExitValue = true
            }

            checkJavaccError(execResult.exitValue)
        }
    }

    private fun withClasspathJavaccRunner(action: JavaccRunner.() -> Unit) {
        val workQueue = exec.classLoaderIsolation { classpath.from(javaccClasspath) }
        action { actionArgs ->
            workQueue.submit(JavaccRunnerWorkAction::class) { arguments.set(actionArgs) }
        }
        workQueue.await()
    }

    private fun interface JavaccRunner {
        fun runJavacc(args: List<String>)
    }

    interface JavaccCommandLineParameters : WorkParameters {
        val arguments: ListProperty<String>
    }

    abstract class JavaccRunnerWorkAction @Inject constructor() : WorkAction<JavaccCommandLineParameters> {
        override fun execute() {
            Class.forName(JAVACC_MAIN_CLASS)
                .getMethod("mainProgram", Array<String>::class.java)
                .invoke(null, parameters.arguments.get().toTypedArray())
                .let { checkJavaccError(it as Int) }
        }
    }
}

private fun checkJavaccError(errorCode: Int) {
    if (errorCode != 0) {
        throw IllegalStateException("Javacc failed with error code: $errorCode")
    }
}
