package com.correx.infrastructure.workflow

import com.correx.core.events.types.ArtifactId
import com.correx.core.transitions.conditions.AllOf
import com.correx.core.transitions.conditions.AlwaysTrue
import com.correx.core.transitions.conditions.AnyOf
import com.correx.core.transitions.conditions.ArtifactAbsent
import com.correx.core.transitions.conditions.ArtifactFieldEquals
import com.correx.core.transitions.conditions.ArtifactPresent
import com.correx.core.transitions.conditions.ArtifactValidated
import com.correx.core.transitions.conditions.FieldOperator
import com.correx.core.transitions.conditions.Not
import com.correx.core.transitions.conditions.TasksReady
import com.correx.core.transitions.conditions.VariableEquals
import com.correx.core.transitions.graph.TransitionCondition

fun ConditionSpec.toCondition(): TransitionCondition = when (type) {
    "always_true" -> AlwaysTrue
    "artifact_present" -> buildArtifactPresent()
    "artifact_absent" -> buildArtifactAbsent()
    "artifact_validated" -> buildArtifactValidated()
    "variable_equals" -> buildVariableEquals()
    "artifact_field_equals" -> buildArtifactFieldEquals()
    "tasks_ready" -> TasksReady
    "all_of" -> AllOf(conditions.map { it.toCondition() })
    "any_of" -> AnyOf(conditions.map { it.toCondition() })
    "not" -> Not((condition ?: error("condition required for not")).toCondition())
    else -> throw WorkflowValidationException("unknown condition type: $type")
}

private fun ConditionSpec.buildArtifactPresent() =
    ArtifactPresent(ArtifactId(artifactId ?: error("artifact_id required for artifact_present")))

private fun ConditionSpec.buildArtifactAbsent() =
    ArtifactAbsent(ArtifactId(artifactId ?: error("artifact_id required for artifact_absent")))

private fun ConditionSpec.buildArtifactValidated() =
    ArtifactValidated(ArtifactId(artifactId ?: error("artifact_id required for artifact_validated")))

private fun ConditionSpec.buildVariableEquals() =
    VariableEquals(
        key ?: error("key required for variable_equals"),
        value ?: error("value required for variable_equals"),
    )

private fun ConditionSpec.buildArtifactFieldEquals() =
    ArtifactFieldEquals(
        artifactId = ArtifactId(artifactId ?: error("artifact_id required for artifact_field_equals")),
        field = field ?: error("field required for artifact_field_equals"),
        value = value ?: error("value required for artifact_field_equals"),
        operator = operator?.let { FieldOperator.fromString(it) } ?: FieldOperator.EQ,
    )
