package de.kif.backend

import mu.KotlinLogging
import java.io.InputStream
import java.nio.file.*

/**
 * Manage static resource files of the ui
 */
object Resources {

    private val logger = KotlinLogging.logger {}

    /**
     * Extract web directory from jar file.
     *
     * @return File that points the extracted web directory.
     */
    private fun extractWeb() {
        val destination: Path = Configuration.Path.webPath

        val classPath = "web"
        val uri = this::class.java.classLoader.getResource(classPath)?.toURI()

        if (uri == null) {
            logger.warn { "Cannot extract web content" }
            return
        }

        val fileSystem: FileSystem?
        val src: Path = if (uri.scheme == "jar") {
            fileSystem = FileSystems.newFileSystem(uri, mutableMapOf<String, Any?>())
            fileSystem.getPath(classPath)
        } else {
            Paths.get(uri)
        }

        Files.walk(src).forEach { path: Path ->
            val name = path.toAbsolutePath().toString().let { name ->
                name.drop(classPath.length + name.indexOf(classPath, ignoreCase = true)).dropWhile {
                    it == '/' || it == '\\'
                }
            }
            if (Files.isDirectory(path)) {
                Files.createDirectories(destination.resolve(name))
            } else {
                Files.copy(path, destination.resolve(name))
            }
        }

        logger.info { "Successfully extract web content" }
    }

    fun deleteUpload(name: String) {
        Files.deleteIfExists(Configuration.Path.uploadsPath.resolve(name))
    }

    fun existsUpload(name: String): Boolean {
        return Files.exists(Configuration.Path.uploadsPath.resolve(name))
    }

    fun createUpload(name: String, input: InputStream) {
        Files.copy(input, Configuration.Path.uploadsPath.resolve(name))
    }

    /**
     * List of js modules to be included.
     */
    val jsModules by lazy {
        Configuration.Path.webPath.toFile().list().toList().filter {
            it.endsWith(".js") &&
                    !it.endsWith(".meta.js") &&
                    !it.endsWith("-test.js") &&
                    it != "require.min.js"
        }.joinToString(", ") { "'${it.take(it.length - 3)}'" }
    }

    fun init() {
        Files.createDirectories(Configuration.Path.databasePath.parent)
        Files.createDirectories(Configuration.Path.sessionsPath)
        Files.createDirectories(Configuration.Path.uploadsPath)
        Files.createDirectories(Configuration.Path.webPath)

        logger.info { "Database path: ${Configuration.Path.databasePath}" }
        logger.info { "Sessions path: ${Configuration.Path.sessionsPath}" }
        logger.info { "Uploads path: ${Configuration.Path.uploadsPath}" }
        logger.info { "Web path: ${Configuration.Path.webPath}" }

        logger.info { "Extract web content..." }
        extractWeb()
    }
}
