/*
 * This file is part of LibEuFin.
 * Copyright (C) 2024, 2025, 2026 Taler Systems S.A.

 * LibEuFin is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3, or
 * (at your option) any later version.

 * LibEuFin is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
 * Public License for more details.

 * You should have received a copy of the GNU Affero General Public
 * License along with LibEuFin; see the file COPYING.  If not, see
 * <http://www.gnu.org/licenses/>
 */

import org.junit.Test
import tech.libeufin.nexus.*
import tech.libeufin.nexus.iso20022.*
import tech.libeufin.ebics.*
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.Path
import kotlin.io.path.exists
import kotlin.io.path.isDirectory
import kotlin.io.path.listDirectoryEntries

class Iso20022Test {
    @Test
    fun sample() {
        for (sample in Path("sample").listDirectoryEntries()) {
            if (sample.isDirectory()) {
                for (case in sample.listDirectoryEntries()) {
                    val content = Files.newInputStream(case)
                    val name = case.toString()
                    println(name)
                    if (name.contains("HAC")) {
                        parseCustomerAck(content)
                    } else if (name.contains("pain.002") || name.contains("pain002") ) {
                        parseCustomerPaymentStatusReport(content)
                    } else {
                        parseTx(content)
                    }
                }
                
            } else {
                val content = Files.newInputStream(sample)
                val name = sample.toString()
                println(name)
                if (name.contains("HAC")) {
                    parseCustomerAck(content)
                } else if (name.contains("pain.002") || name.contains("pain002") ) {
                    parseCustomerPaymentStatusReport(content)
                } else {
                    parseTx(content)
                }
            }
        }
    }

    @Test
    fun logs() {
        val root = Path("test")
        if (!root.exists()) return
        for (platform in root.listDirectoryEntries()) {
            if (!platform.isDirectory() || platform.fileName.toString() == "platform") continue

            // List logs
            var logs = mutableListOf<Path>()
            for (file in platform.listDirectoryEntries()) {
                if (!file.isDirectory()) continue
                when (file.fileName.toString()) {
                    "fetch" -> for (transaction in file.listDirectoryEntries()) {
                        if (transaction.isDirectory()) {
                            logs.addAll(transaction.listDirectoryEntries())
                        }
                    }
                    "submit" -> {}
                    else -> for (transaction in file.listDirectoryEntries()) {
                        when (transaction.fileName.toString()) {
                            "fetch" -> logs.addAll(transaction.listDirectoryEntries())
                            "submit" -> {}
                            else -> {
                                var payload = transaction.resolve("payload")
                                if (payload.exists()) {
                                    logs.addAll(payload.listDirectoryEntries())
                                    continue
                                }
                                payload = transaction.resolve("payload.xml")
                                if (payload.exists()) {
                                    logs.add(payload)
                                }
                            }
                        }
                    }
                }
            }

            // Load config
            val path = root.resolve("platform").resolve("${platform.fileName}.conf")
            if (!path.exists()) continue
            val cfg = nexusConfig(root.resolve("platform").resolve("${platform.fileName}.conf"))
            val currency = cfg.currency
            val dialect = cfg.ebics.dialect
            // Parse logs
            for (log in logs) {
                val content = Files.newInputStream(log)
                val name = log.toString()
                println(name)
                if (name.contains("wssparam") || name.endsWith(".txt")) {
                    // Skip
                } else if (name.contains("HAC")) {
                    parseCustomerAck(content)
                } else if (name.contains("HAA")) {
                    EbicsAdministrative.parseHAA(content)
                } else if (name.contains("HKD")) {
                    EbicsAdministrative.parseHKD(content)
                } else if (name.contains("pain.002")) {
                    parseCustomerPaymentStatusReport(content)
                } else {
                    parseTx(content)
                }
            }
        }
    }
}