import io.airbyte.gradle.DockerGenerateConnectorBuildArgs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.RegularFile
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.provider.Provider

class AirbyteConnectorDockerConventionPlugin implements Plugin<Project> {
    private static final String SHARED_DOCKERFILE = 'docker-images/Dockerfile.java-connector-non-airbyte-ci'

    @Override
    void apply(Project project) {
        /*
            We deliberately avoid importing classes from the published Airbyte Docker
            plugin. That keeps buildSrc free of a compile‑time dependency on a specific
            plugin version and lets this convention plugin compile before external
            plugins are resolved.
         */

        project.plugins.withId('io.airbyte.gradle.docker') {
            def dockerExt = ((project.extensions.findByName('airbyte') as ExtensionAware)
                    ?.extensions?.findByName('docker'))

            if (!dockerExt) {
                project.logger.warn('airbyte.docker extension not found; skipping convention plugin.')
                return
            }

            /* ------------------------------------------------------------
             * 1. imageName default = project.name (if not already set)
             * ------------------------------------------------------------ */
            if (!dockerExt.imageName.present) {
                dockerExt.imageName.convention(project.name)
            }

            /* ------------------------------------------------------------
             * 2. Use shared Dockerfile if not overridden. This allows
             *    users to specify the Dockerfiles per connector.
             *    The core plugin’s dockerCopyDockerfile task will copy
             *    it into build/airbyte/docker/Dockerfile automatically.
             * ------------------------------------------------------------ */
            def userFile = dockerExt.dockerfile.get().asFile
            if (!userFile.exists()) {
                dockerExt.dockerfile.set(project.rootProject.file(SHARED_DOCKERFILE))
            }

            /* ------------------------------------------------------------
             * 3. Task: generate buildArgs.properties from metadata.yaml
             * ------------------------------------------------------------ */
            def genProps = project.tasks.register(
                    'generateConnectorDockerBuildArgs',
                    DockerGenerateConnectorBuildArgs
            ) {
                metadata.set(project.layout.projectDirectory.file('metadata.yaml'))
                output.set(project.layout.buildDirectory.file('docker/buildArgs.properties'))
            }

            /* ------------------------------------------------------------
             * 4. Lazy provider: read and inject the file generated by the
             *    DockerGenerateConnectorBuildArgs task as buildArgs
             * ------------------------------------------------------------ */
            def propsMapProvider = project.providers
                    .fileContents(genProps.flatMap { it.output } as Provider<RegularFile>)
                    .asText
                    .map { txt ->
                        txt.readLines()
                                .findAll { it.contains('=') }
                                .collectEntries { ln ->
                                    def (k, v) = ln.split('=', 2)
                                    [(k.trim()): v.trim()]
                                }
                    }
            dockerExt.buildArgs.putAll(propsMapProvider)

            /* ------------------------------------------------------------
             * 5. Make dockerBuildx depend on the generator, and register
             *    the properties file as an input (incremental build‑cache)
             * ------------------------------------------------------------ */
            project.tasks.named('dockerBuildx').configure { Task t ->
                t.dependsOn(genProps)
                t.inputs.file(genProps.flatMap { it.output })
            }
        }
    }
}
