package kotlinx.schema.ksp.gradle.plugin

import org.gradle.api.provider.Property
import javax.inject.Inject

/**
 * Extension for configuring the Kotlinx Schema Gradle plugin.
 *
 * Example usage:
 * ```kotlin
 * kotlinxSchema {
 *     enabled.set(true)
 *     rootPackage.set("com.example.models")
 *     withSchemaObject.set(true)
 * }
 * ```
 */
public abstract class KotlinxSchemaExtension
    @Inject
    constructor() {
        /**
         * Whether schema generation is enabled.
         * Default: true
         */
        public abstract val enabled: Property<Boolean>

        /**
         * Optional root package to limit processing to. If set, only classes in this package
         * (or its subpackages) will be processed by KSP. If not set, all packages are processed.
         */
        public abstract val rootPackage: Property<String>

        /**
         * Whether to generate the jsonSchema JsonObject property in addition to jsonSchemaString.
         * When enabled, both extension properties are generated:
         * - jsonSchemaString: String
         * - jsonSchema: JsonObject
         *
         * Default: true
         */
        public abstract val withSchemaObject: Property<Boolean>

        /**
         * Configures the visibility of schema extension functions/properties generated by the
         * Kotlinx Schema Gradle plugin. This property determines the modifier
         * (e.g., "public", "internal") applied to the generated schema-related APIs.
         *
         * Value should be a valid visibility modifier supported by the Kotlin language.
         *
         * Default: "" i.e., no visibility modifier by default
         */
        public abstract val visibility: Property<String>

        /**
         * Comma- or semicolon-separated glob patterns of fully qualified names to include in schema generation.
         * Applies to both classes and functions. If not set, all symbols within [rootPackage] are included.
         *
         * Glob syntax: `*` matches within one package segment, `**` matches across segments, `?` matches one character.
         *
         * Example: `com.example.api.**, com.example.dto.**.*Dto`
         */
        public abstract val include: Property<String>

        /**
         * Comma- or semicolon-separated glob patterns of fully qualified names to exclude from schema generation.
         * Applies to both classes and functions. Exclusions are applied after [include]; a symbol matching any
         * exclude pattern is always skipped.
         *
         * Example: `**.internal.**, **.*Internal`
         */
        public abstract val exclude: Property<String>

        init {
            // Set default values
            enabled.convention(true)
            withSchemaObject.convention(false) // Disabled by default; set to true to generate a typed jsonSchema object
            rootPackage.unsetConvention() // rootPackage intentionally has no default; absence means no filtering
            visibility.convention("") // no visibility modifier by default
            include.unsetConvention() // absence means no include filtering
            exclude.unsetConvention() // absence means no exclude filtering
        }
    }
