package com.infendro.cli.command.context import com.infendro.cli.Dsl import com.infendro.cli.command.Argument import com.infendro.cli.command.Command import com.infendro.cli.command.Option import kotlin.reflect.KProperty @Dsl class Context internal constructor( val command: Command, val commands: List, val arguments: List, val options: List, ) { class Cmd( val name: String, ) class Arg( val value: Any, ) class Opt( val name: String, val value: Any, ) internal fun execute() = (command.execute)() fun help() { command.help?.let { println(it) } } operator fun Command.Key.getValue(thisRef: Any?, property: KProperty<*>): String = commands[index].name private val Argument.index: Int get() = command.arguments.takeWhile { it != this }.sumOf { it.count } @Suppress("UNCHECKED_CAST") private val Argument.value: T? get() = arguments.getOrNull(index)?.value as? T @Suppress("UNCHECKED_CAST") private val Argument.Variable.values: List get() = arguments.drop(index).take(count).map { it.value as T } operator fun Argument.Required.getValue(thisRef: Any?, property: KProperty<*>): T = value!! operator fun Argument.OrElse.getValue(thisRef: Any?, property: KProperty<*>): T = value ?: other operator fun Argument.OrNull.getValue(thisRef: Any?, property: KProperty<*>): T? = value operator fun Argument.Variable.getValue(thisRef: Any?, property: KProperty<*>): List = values @Suppress("UNCHECKED_CAST") private val Option.value: T? get() = options.firstOrNull { it.name in names }?.value as? T @Suppress("UNCHECKED_CAST") private val Option.Variable.values: List get() = options.filter { it.name in names }.map { it.value as T } operator fun Option.Required.getValue(thisRef: Any?, property: KProperty<*>): T = value!! operator fun Option.OrElse.getValue(thisRef: Any?, property: KProperty<*>): T = value ?: other operator fun Option.OrNull.getValue(thisRef: Any?, property: KProperty<*>): T? = value operator fun Option.Variable.getValue(thisRef: Any?, property: KProperty<*>): List = values }