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

import com.yandex.direct.api.v5.campaigns.ArchiveRequest
import com.yandex.direct.api.v5.general.IdsCriteria
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import ru.yandex.direct.api.v5.entity.campaigns.validation.CampaignsCommonRequestValidator.validateCampaignsAreSupported
import ru.yandex.direct.api.v5.validation.DefectType
import ru.yandex.direct.api.v5.validation.DefectTypes.maxElementsInSelection
import ru.yandex.direct.api.v5.validation.constraints.Constraints.eachNotNull
import ru.yandex.direct.api.v5.validation.constraints.Constraints.maxListSize
import ru.yandex.direct.api.v5.validation.constraints.Constraints.notEmptyCollection
import ru.yandex.direct.api.v5.validation.constraints.Constraints.notNull
import ru.yandex.direct.core.entity.campaign.service.CampaignService
import ru.yandex.direct.validation.builder.ItemValidationBuilder
import ru.yandex.direct.validation.builder.When
import ru.yandex.direct.validation.result.ValidationResult

@Component
class CampaignsArchiveRequestValidator @Autowired constructor(
    private val campaignService: CampaignService
) {
    fun validateExternalRequest(externalRequest: ArchiveRequest): ValidationResult<ArchiveRequest, DefectType> {
        val vb = ItemValidationBuilder.of<ArchiveRequest, DefectType>(externalRequest)
        vb.item(
            externalRequest.selectionCriteria,
            ArchiveRequest.PropInfo.SELECTION_CRITERIA.schemaName.localPart
        ).check(notNull())
            .checkBy(::validateIdsCriteria, When.isValid())
        return vb.result
    }

    private fun validateIdsCriteria(idsCriteria: IdsCriteria): ValidationResult<IdsCriteria, DefectType> {
        val vb = ItemValidationBuilder.of<IdsCriteria, DefectType>(idsCriteria)
        vb.item(idsCriteria.ids, "Ids")
            .check(notNull(), When.isValid())
            .check(notEmptyCollection(), When.isValid())
            .check(eachNotNull(), When.isValid())
            .check(
                maxListSize(MAX_ARCHIVE_IDS_COUNT),
                maxElementsInSelection(MAX_ARCHIVE_IDS_COUNT),
                When.isValid()
            )
        return vb.result
    }

    fun validateInternalRequest(internalRequest: List<Long>): ValidationResult<List<Long>, DefectType> {
        val campaignTypeSourceByCids = campaignService.getCampaignsTypeSourceMap(internalRequest, true)
        return validateCampaignsAreSupported(internalRequest, campaignTypeSourceByCids, false)
    }

    companion object {
        private const val MAX_ARCHIVE_IDS_COUNT = 1000
    }
}
