package ru.yandex.direct.api.v5.entity.adgroups.validation

import org.springframework.stereotype.Component
import ru.yandex.direct.api.v5.entity.adgroups.container.AdGroupsContainer
import ru.yandex.direct.api.v5.entity.adgroups.validation.type.AdGroupsInternalRequestValidationTypeSupport
import ru.yandex.direct.api.v5.validation.DefectType
import ru.yandex.direct.validation.result.ValidationResult
import ru.yandex.direct.validation.result.ValidationResultUtils

@Component
class AdGroupsInternalRequestValidationTypeSupportFacade(validators: List<AdGroupsInternalRequestValidationTypeSupport<*>>) {
    private val validatorByType = validators.associateBy { it.typeClass }

    fun validate(internalRequest: List<AdGroupsContainer>): ValidationResult<List<AdGroupsContainer>, DefectType> {
        val resultByItem = internalRequest
            .groupBy { it.javaClass }
            .asSequence()
            .flatMap { (type, items) ->
                val validator = validatorByType[type]
                    ?: throw IllegalStateException("no validation type support for $type")
                items.asSequence().zip(validateItems(validator, items).asSequence())
            }
            .toMap()
        return ValidationResultUtils.mergeValidationResults(internalRequest, internalRequest.map { resultByItem[it] })
    }

    private fun <T : AdGroupsContainer> validateItems(validator: AdGroupsInternalRequestValidationTypeSupport<T>, items: List<AdGroupsContainer>) =
        validator.validate(@Suppress("UNCHECKED_CAST") (items as List<T>))
}
