// RUN_PIPELINE_TILL: FRONTEND
// LANGUAGE: +ForbidRecursiveDelegateExpressions
// WITH_STDLIB

import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty1

inline fun <reified Self : DatabaseEntity, reified Target : DatabaseEntity> Self.parent(
    property: KProperty1<Target, MutableCollection<Self>>): Delegate<Self, Target?> = TODO()

class GitLabBuildProcessor: DatabaseEntity {
    var processor by <!DEBUG_INFO_EXPRESSION_TYPE("Delegate<GitLabBuildProcessor, GitLabChangesProcessor?>")!>parent(GitLabChangesProcessor::buildProcessors)<!>
}

interface DatabaseEntity: Entity
interface Entity
interface ResourceFactory<T, R>
interface ValueFilter<K>

interface Delegate<R : Entity, T> : ReadWriteProperty<R, T>, ValueFilter<R> {
    infix fun name(desc: KProperty<*>): String
infix fun by(name: String): Delegate<R, T>
infix fun resource(factory: ResourceFactory<R, T>): Delegate<R, T>
infix fun filter(filter: (R, Any?) -> Boolean): Delegate<R, T>
}

class GitLabChangesProcessor: DatabaseEntity {
    var buildProcessors by <!DEBUG_INFO_EXPRESSION_TYPE("Delegate<GitLabChangesProcessor, kotlin.collections.MutableCollection<GitLabBuildProcessor>>"), TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM_ERROR!>child_many(
        GitLabBuildProcessor::class.java,
        GitLabBuildProcessor::processor
    )<!>
}

fun <Self : DatabaseEntity, Target : DatabaseEntity> Self.child_many(
    clazz: Class<Target>, property: KProperty1<Target, Self?>, name: String = property.name
): Delegate<Self, MutableCollection<Target>> = TODO() // Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly

/* GENERATED_FIR_TAGS: callableReference, classDeclaration, classReference, funWithExtensionReceiver,
functionDeclaration, functionalType, infix, inline, interfaceDeclaration, nullableType, propertyDeclaration,
propertyDelegate, reified, setter, starProjection, typeConstraint, typeParameter */
