package ru.yandex.direct.web.entity.uac.validation

import ru.yandex.direct.core.entity.banner.type.measurers.model.BannerMeasurerParamsWeborama
import ru.yandex.direct.core.entity.uac.repository.ydb.model.UacBannerMeasurerSystem
import ru.yandex.direct.core.entity.uac.repository.ydb.model.UacMeasurer
import ru.yandex.direct.utils.JsonUtils
import ru.yandex.direct.validation.builder.Constraint
import ru.yandex.direct.validation.builder.When
import ru.yandex.direct.validation.constraint.CommonConstraints
import ru.yandex.direct.validation.defect.CommonDefects
import ru.yandex.direct.validation.result.Defect
import ru.yandex.direct.validation.result.ValidationResult
import ru.yandex.direct.validation.util.validateObject
import ru.yandex.direct.validation.wrapper.DefaultValidator

class CpmUacMeasurersValidator (
    private val hasActiveMediascopeSettings: Boolean
): DefaultValidator<UacMeasurer> {
    override fun apply(m: UacMeasurer): ValidationResult<UacMeasurer, Defect<*>> {
        return validateObject(m) {
            check(CommonConstraints.notNull())

            //пока поддерживем только вебораму и mediascope на уровне баннера
            check(Constraint.fromPredicate({ x: UacMeasurer ->
                setOf(UacBannerMeasurerSystem.WEBORAMA, UacBannerMeasurerSystem.MEDIASCOPE).contains(x.measurerType)
            }, CommonDefects.invalidValue()), When.isValid())

            check(Constraint.fromPredicate({x: UacMeasurer -> checkParam(x)}, CommonDefects.invalidValue()), When.isValid())
        }
    }

    private fun checkParam(x: UacMeasurer): Boolean {
        return when (x.measurerType) {
            UacBannerMeasurerSystem.WEBORAMA -> validateWeboramaParams(x)
            UacBannerMeasurerSystem.MEDIASCOPE -> validateMediascopeParams(x)
            else -> x.params.isEmpty()//для остальных должна быть пустая строка в качестве параметра
        }
    }

    private fun validateMediascopeParams(x: UacMeasurer): Boolean {
        return x.params.isEmpty() && hasActiveMediascopeSettings
    }

    private fun validateWeboramaParams(x: UacMeasurer): Boolean {
        val par = try {
            JsonUtils.fromJson(x.params, BannerMeasurerParamsWeborama::class.java)
        } catch (e: Exception) {
            null
        }
        return par != null && par.clientId != null && par.insertionId != null && par.creativeId != null &&
            par.clientId > 0 && par.insertionId > 0 && par.creativeId > 0
    }
}
