package net.taehui.twilight

import com.fasterxml.jackson.annotation.JsonValue
import org.apache.commons.io.FileUtils
import org.apache.commons.io.FilenameUtils
import java.nio.ByteBuffer
import java.nio.channels.AsynchronousFileChannel
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.StandardCopyOption

class BundleIO(
    private val bundleFilePath: Path,
    val fileChannel: AsynchronousFileChannel,
    val bundleName: String,
    val bundleVariety: BundleVariety,
    val etc: String,
    val bundleFileName: String,
    private val isSaveAs: Boolean
) : AutoCloseable {
    enum class BundleVariety(@JvmField val value: Int, val fileVariety: String) {
        DEFAULT_UI(-2, ".zip"), DEFAULT_NOTE(-1, ".zip"), UI(1, ".zip"), QWILIGHT(
            2,
            ".zip"
        ),
        EVENT_NOTE(3, ".txt"), NOTE(4, ".zip"), NET(5, ".zip");

        @JsonValue
        fun getValue(): Int {
            return value
        }

        companion object {
            fun getBundleVariety(value: Int): BundleVariety {
                return when (value) {
                    1 -> UI
                    2 -> QWILIGHT
                    3 -> EVENT_NOTE
                    4 -> NOTE
                    5 -> NET
                    else -> throw IllegalArgumentException(value.toString())
                }
            }
        }
    }

    val data: ByteBuffer = ByteBuffer.allocateDirect(SEND_UNIT)
    var filePosition = 0

    fun setFileVariety() {
        Files.move(
            bundleFilePath,
            Paths.get(FilenameUtils.removeExtension(bundleFilePath.toString()) + bundleVariety.fileVariety),
            StandardCopyOption.REPLACE_EXISTING
        )
    }

    fun saveFilePosition(filePosition: Int): Boolean {
        this.filePosition += filePosition
        return this.filePosition > when (bundleVariety) {
            BundleVariety.NET -> TwilightComponent.NET_BUNDLE_LENGTH
            else -> TwilightComponent.BUNDLE_LENGTH
        }
    }

    fun getBundleLength(): Long {
        return fileChannel.size()
    }

    override fun close() {
        fileChannel.close()
        if (isSaveAs) {
            FileUtils.deleteQuietly(bundleFilePath.toFile())
        }
    }

    companion object {
        const val SEND_UNIT = 1024 * 1024
    }
}