/*
 * This file is part of LibEuFin.
 * Copyright (C) 2024-2025 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/>
 */

package tech.libeufin.bank.cli

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.parameters.groups.provideDelegate
import tech.libeufin.bank.bankConfig
import tech.libeufin.bank.corebankWebApp
import tech.libeufin.bank.logger
import tech.libeufin.bank.withDb
import tech.libeufin.common.TalerCmd
import tech.libeufin.common.api.serve
import kotlin.io.path.Path
import kotlin.io.path.exists
import kotlin.io.path.readText

class Serve: TalerCmd("serve") {
    override fun help(context: Context) = "Run libeufin-bank HTTP server"

    override fun run() = cliCmd(logger) {
        bankConfig(config).withDb { db, cfg ->
            if (cfg.allowConversion) {
                logger.info("Ensure exchange account exists")
                val info = db.account.bankInfo("exchange")
                if (info == null) {
                    throw Exception("Exchange account missing: an exchange account named 'exchange' is required for conversion to be enabled")
                } else if (!info.isTalerExchange) {
                    throw Exception("Account is not an exchange: an exchange account named 'exchange' is required for conversion to be enabled")
                }
                logger.info("Ensure conversion is enabled")
                val sqlProcedures = Path("${cfg.dbCfg.sqlDir}/libeufin-conversion-setup.sql")
                if (!sqlProcedures.exists()) {
                    throw Exception("Missing libeufin-conversion-setup.sql file")
                }
                db.conn { it.execSQLUpdate(sqlProcedures.readText()) }
            } else {
                logger.info("Ensure conversion is disabled")
                val sqlProcedures = Path("${cfg.dbCfg.sqlDir}/libeufin-conversion-drop.sql")
                if (!sqlProcedures.exists()) {
                    throw Exception("Missing libeufin-conversion-drop.sql file")
                }
                db.conn { it.execSQLUpdate(sqlProcedures.readText()) }
                // Remove conversion info from the database ?
            }
            serve(cfg.serverCfg, logger) {
                corebankWebApp(db, cfg)
            }
        }
    }
}