package kr.or.bok.rtgs.common

import kr.or.bok.rtgs.common.iso20022.Iso20022Codec
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue

class CommonTest {

    @Test
    fun `bmi is 22 digits and increments`() {
        val gen = BmiGenerator("1001")
        val a = gen.next()
        val b = gen.next()
        assertEquals(22, a.length)
        assertEquals("1001", BmiGenerator.orgCodeOf(a))
        assertTrue(b > a)
    }

    @Test
    fun `quorum thresholds`() {
        assertEquals(1, QuorumContext("DC1", 1).quorum)
        assertEquals(2, QuorumContext("DC1", 3).quorum)
        assertTrue(QuorumContext("DC1", 3).canServe(2))   // 1센터 다운 -> 지속
        assertTrue(!QuorumContext("DC1", 3).canServe(1))  // 2센터 다운 -> 장애
    }

    @Test
    fun `core message rejects self-transfer and non-positive amount`() {
        assertFailsWith<IllegalArgumentException> {
            CoreMessage("b", "t", "1001", "1001", "d", "c", 100, origHash = "h")
        }
        assertFailsWith<IllegalArgumentException> {
            CoreMessage("b", "t", "1001", "1002", "d", "c", 0, origHash = "h")
        }
    }

    @Test
    fun `parse official pacs008 and extract core message`() {
        val xml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
              <FIToFICstmrCdtTrf>
                <GrpHdr>
                  <MsgId>2026070810010000000001</MsgId>
                  <CreDtTm>2026-07-08T17:00:00</CreDtTm>
                  <NbOfTxs>1</NbOfTxs>
                  <SttlmInf><SttlmMtd>CLRG</SttlmMtd></SttlmInf>
                </GrpHdr>
                <CdtTrfTxInf>
                  <PmtId><EndToEndId>2026070810010000000001</EndToEndId></PmtId>
                  <IntrBkSttlmAmt Ccy="KRW">150</IntrBkSttlmAmt>
                  <ChrgBr>SLEV</ChrgBr>
                  <Dbtr><Nm>BANK-1001</Nm></Dbtr>
                  <DbtrAcct><Id><Othr><Id>ACC-1001</Id></Othr></Id></DbtrAcct>
                  <DbtrAgt><FinInstnId><ClrSysMmbId><MmbId>1001</MmbId></ClrSysMmbId></FinInstnId></DbtrAgt>
                  <CdtrAgt><FinInstnId><ClrSysMmbId><MmbId>1002</MmbId></ClrSysMmbId></FinInstnId></CdtrAgt>
                  <Cdtr><Nm>BANK-1002</Nm></Cdtr>
                  <CdtrAcct><Id><Othr><Id>ACC-1002</Id></Othr></Id></CdtrAcct>
                </CdtTrfTxInf>
              </FIToFICstmrCdtTrf>
            </Document>
        """.trimIndent()
        val req = Iso20022Codec.parsePacs008(xml)
        assertEquals("1001", req.from)
        assertEquals("1002", req.to)
        assertEquals("ACC-1001", req.dbtrAcct)
        assertEquals(150, req.amount)
        assertEquals("KRW", req.ccy)
        val core = Iso20022Codec.toCoreMessage(req, xml, assignedBmi = "X")
        assertEquals("2026070810010000000001", core.bmi)
        assertEquals(64, core.origHash.length) // SHA-256 hex
    }
}
