package com.ustadmobile.lib.rest.ext

import com.ustadmobile.lib.rest.CONF_DBMODE_SINGLETON
import io.ktor.server.config.*
import java.io.File

const val DEFAULT_DATA_DIR_NAME = "data"

fun ApplicationConfig.dbModeProperty(): String {
    return propertyOrNull("ktor.ustad.dbmode")?.getString() ?: CONF_DBMODE_SINGLETON
}

/**
 * Find the ktor server app source directory if/when the server is being run from source (e.g. via
 * gradlew command).
 *
 * When using the ./gradlew command or a gradle task in the IDE the working directory will be the
 * app-ktor-server module itself.
 *
 * When running as a Kotlin Program (e.g. clicking play next to main function), then the working
 * directory will be the project root directory.
 *
 */
fun ktorAppSourceDir(): File? {
    val userDirFile = File(System.getProperty("user.dir"))
    return when {
        //running in the app-ktor-server directory
        userDirFile.name == "app-ktor-server" && File(userDirFile, "build.gradle").exists() -> userDirFile

        //running in the root source directory
        File(userDirFile, "settings.gradle").exists() &&
                File(userDirFile, "app-ktor-server").exists() -> {
            File(userDirFile, "app-ktor-server")
        }

        else -> null
    }
}

/*
 *  Find the ktor server app home directory.
 */
fun ktorAppHomeDir(): File {
    val appHomeProp = System.getProperty("app_home")
    val sourceDir: File? =  ktorAppSourceDir()

    return when {
        /*
         * If app home is explicitly set (which will be the case for the production version that
         * uses the binary script generated by Gradle application plugin) then accept this as the
         * app home dir
         */
        appHomeProp != null -> File(appHomeProp)

        /*
         * If app home is not explicitly set, and the current home directory is the root source
         * directory, then the app home directory is (current-working-directory)/app-ktor-server .
         * This will be the case when running via the IDE (by clicking run/debug on ServerAppMain).
         */
        sourceDir != null -> sourceDir

        /*
         * Else use the current working directory
         */
        else -> File(System.getProperty("user.dir"))
    }
}

/**
 * The location of the server.properties file. When admin commands are run (e.g. newlearningspace etc)
 * the command line client needs to connect to the server over http. The admin command needs to have
 * authorization and needs to know the server port.
 *
 * This is secure because anyone who has access to the server.properties file would also have access
 * to the server directory itself.
 */
fun ktorServerPropertiesFile(
    dataDir: File
): File {
    return File(dataDir, "server.properties")
}

/**
 * Get a File for a property e.g. for the data directory or well known directory
 *
 * @param propertyName the config property name
 * @param defaultPath default value of property is null
 *
 * @return File object - if the path is absolute, returns the absolute File as is. If not, then will
 * return file relative to the server path as per ktorAppHomeDir()
 */
fun ApplicationConfig.fileProperty(
    propertyName: String, defaultPath: String
): File {
    val path = propertyOrNull(propertyName)?.getString() ?: defaultPath
    val file = File(path)

    return if(file.isAbsolute) {
        file
    }else {
        File(ktorAppHomeDir(), path)
    }
}


fun ApplicationConfig.absoluteDataDir() = fileProperty(
    propertyName = "ktor.ustad.datadir", defaultPath = DEFAULT_DATA_DIR_NAME
)

