// tag::java-configuration-example[]
// declare a "configuration" named "implementation"
val implementation = configurations.create("implementation") {
    isCanBeConsumed = false
    isCanBeResolved = false
}

// tag::declare-configuration[]
dependencies {
    // add a project dependency to the implementation configuration
    implementation(project(":lib"))
}
// end::declare-configuration[]

// tag::concrete-classpath[]
configurations {
    // declare a resolvable configuration that is going to resolve the compile classpath of the application
// end::java-configuration-example[]

    // Using lazy & newer API: realized only when needed
// tag::java-configuration-example[]
    resolvable("compileClasspath") {
        extendsFrom(implementation)
    }
// end::java-configuration-example[]
    // Using lazy & older API: realized only when needed
    register("compileClasspath-lazy") {
        isCanBeConsumed = false
        isCanBeDeclared = false
        extendsFrom(implementation)
    }
    // Using eager & older API: realized immediately - avoid
    create("compileClasspath-eager") {
        isCanBeConsumed = false
        isCanBeDeclared = false
        extendsFrom(implementation)
    }
// tag::java-configuration-example[]
// end::concrete-classpath[]
    // declare a resolvable configuration that is going to resolve the runtime classpath of the application
    resolvable("runtimeClasspath") {
        extendsFrom(implementation)
    }
// tag::concrete-classpath[]
}
// end::concrete-classpath[]

// tag::setup-configurations[]
configurations {
    // a consumable configuration meant for consumers that need the API of this component
// end::java-configuration-example[]

    // Using lazy & newer API: realized only when needed
// tag::java-configuration-example[]
    consumable("exposedApi") {
        extendsFrom(implementation)
    }
// end::java-configuration-example[]
    // Using lazy & older API: realized only when needed
    register("exposedApi-lazy") {
        isCanBeResolved = false
        isCanBeDeclared = false
        extendsFrom(implementation)
    }
    // Using eager & older API: realized immediately - avoid
    create("exposedApi-eager") {
        isCanBeResolved = false
        isCanBeDeclared = false
        extendsFrom(implementation)
    }
// tag::java-configuration-example[]
// end::setup-configurations[]
    // a consumable configuration meant for consumers that need the implementation of this component
    consumable("exposedRuntime") {
        extendsFrom(implementation)
    }
// tag::setup-configurations[]
}
// end::setup-configurations[]
// end::java-configuration-example[]

// tag::define_attribute[]
// An attribute of type `String`
val myAttribute = Attribute.of("my.attribute.name", String::class.java)
// An attribute of type `Usage`
val myUsage = Attribute.of("my.usage.attribute", Usage::class.java)
// An attribute of an `Enum` type that implements `Named` (plain enums are not supported)
enum class MyEnum : Named {
    FOO, BAR;

    override fun getName(): String = name
}
val myEnumAttribute = Attribute.of("my.enum.attribute", MyEnum::class.java)
// end::define_attribute[]

// tag::register-attributes[]
dependencies.attributesSchema {
    // registers this attribute to the attributes schema
    attribute(myAttribute)
    attribute(myUsage)
}
// end::register-attributes[]

// tag::attributes-on-configurations[]
configurations {
    create("myConfiguration") {
        attributes {
            attribute(myAttribute, "my-value")
        }
    }
}
// end::attributes-on-configurations[]

// tag::named-attributes[]
configurations {
    "myConfiguration" {
        attributes {
            attribute(myUsage, project.objects.named(Usage::class.java, "my-value"))
        }
    }
}
// end::named-attributes[]
