package inn.ocsf.bee.freigeld

import com.github.ulisesbocchio.jar.resources.JarResourceLoader
import inn.ocsf.bee.freigeld.core.demo.DemoInMem
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Profile
import org.springframework.core.task.TaskExecutor
import org.springframework.scheduling.TaskScheduler
import org.springframework.scheduling.annotation.EnableScheduling
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
import org.springframework.stereotype.Service
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import sun.misc.Unsafe
import java.text.SimpleDateFormat
import java.util.*
import javax.annotation.PostConstruct
import javax.inject.Inject


@SpringBootApplication
@EnableScheduling
class FreiApp {

    private val log = LoggerFactory.getLogger(javaClass)

    @PostConstruct
    fun init() {
        Locale.setDefault(Locale("ru", "RU"))
        TimeZone.setDefault(TimeZone.getTimeZone("Europe/Moscow"))
        doTimeTest()
    }

    private fun doTimeTest() {
        val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        val date = Date()
        log.info("started in " + sdf.format(date))
    }

    @Bean
    fun taskExecutor(): TaskExecutor? {
        val ret = ThreadPoolTaskExecutor()
        ret.corePoolSize = 3
        //ret.setMaxPoolSize(1024);
        ret.setQueueCapacity(11)
        return ret
    }

    @Bean
    fun taskScheduler(): TaskScheduler? {
        return ThreadPoolTaskScheduler()
    }

}

@RestController
class DevController {

    @Inject
    private lateinit var demo: DemoInMem

    @RequestMapping("dev/doEx0")
    fun doEx0() {
        demo.tick()
    }
}

@Service
@Profile("dev")
class DevService

fun main(args: Array<String>) {
    disableWarning()
    val context = SpringApplicationBuilder().sources(FreiApp::class.java).resourceLoader(JarResourceLoader()).run(*args)
}

fun disableWarning() {
    try {
        val theUnsafe = Unsafe::class.java.getDeclaredField("theUnsafe")
        theUnsafe.isAccessible = true
        val u = theUnsafe.get(null) as Unsafe
        val cls = Class.forName("jdk.internal.module.IllegalAccessLogger")
        val logger = cls.getDeclaredField("logger")
        u.putObjectVolatile(cls, u.staticFieldOffset(logger), null)
    } catch (e: Exception) {
        // ignore
    }
}