package kr.or.bok.rtgs.common.iso20022

import java.io.StringReader
import javax.xml.XMLConstants
import javax.xml.transform.stream.StreamSource
import javax.xml.validation.Schema
import javax.xml.validation.SchemaFactory

/**
 * XSD 기반 전문 유효성 검사(복원력방안: XSD 스키마로 접수 전문 검증).
 * **정식 ISO 20022 pacs.008.001.08 공식 XSD**(iso20022.org 배포본)로 검증한다(2026-07-10 전환).
 * XSD 리소스가 없으면 검증을 건너뛴다(개발 편의).
 */
class XmlValidator(private val xsdResourcePath: String = "/iso20022/xsd/pacs.008.001.08.xsd") {

    private val schema: Schema? by lazy {
        val stream = javaClass.getResourceAsStream(xsdResourcePath) ?: return@lazy null
        val factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
        // XXE 방어: 외부 엔티티/DTD 차단
        runCatching { factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "") }
        runCatching { factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "") }
        stream.use { factory.newSchema(StreamSource(it)) }
    }

    data class Result(val valid: Boolean, val error: String? = null)

    fun validate(xml: String): Result {
        val s = schema ?: return Result(true) // XSD 미탑재 시 통과
        return try {
            val validator = s.newValidator()
            validator.validate(StreamSource(StringReader(xml)))
            Result(true)
        } catch (e: Exception) {
            Result(false, e.message)
        }
    }
}
