package com.duolebo.blyrobot.web

import android.content.Context
import com.duolebo.blyrobot.util.Constants
import com.minhui.vpn.ProxyConfig
import com.minhui.vpn.VPNConstants
import com.minhui.vpn.VPNConstants.DEFAULT_PACKAGE_ID
import com.minhui.vpn.nat.NatSession
import com.minhui.vpn.utils.TimeFormatUtil
import com.minhui.vpn.utils.VpnServiceHelper
import fi.iki.elonen.NanoHTTPD
import java.util.*
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit

class CaptureWebServer : NanoHTTPD {

    private var context:Context
    private var timer: ScheduledExecutorService? = null
    private var captureList  = ArrayList<NatSession>()

    private var listener: ProxyConfig.VpnStatusListener = object : ProxyConfig.VpnStatusListener {

        override fun onVpnStart(context: Context) {
            startTimer()
        }

        override fun onVpnEnd(context: Context) {
            cancelTimer()
        }
    }

    constructor(port: Int, context: Context) : super("0.0.0.0", port) {
        init()
        this.context = context
    }

    private fun init() {
        ProxyConfig.Instance.registerVpnStatusListener(listener)
        if (VpnServiceHelper.vpnRunningStatus()) {
            startTimer()
        }

        refreshData()
    }

    private fun startTimer() {
        timer = Executors.newSingleThreadScheduledExecutor()
        timer!!.scheduleAtFixedRate(object : TimerTask() {

            override fun run() {
                refreshData()
            }
        }, 1000, 1000, TimeUnit.MILLISECONDS)
    }

    private fun cancelTimer() {
        timer?.run {
            shutdownNow()
        }
        timer = null
    }

    private fun refreshData() {
        val allNetConnection = VpnServiceHelper.getAllSession()
        if (allNetConnection == null || allNetConnection.isEmpty()) {
            return
        }
        val iterator = allNetConnection.iterator()
        val packageName = context.packageName

        val sp = context.getSharedPreferences(VPNConstants.VPN_SP_NAME, Context.MODE_PRIVATE)
        val selectPackage = sp.getString(DEFAULT_PACKAGE_ID, null)
        val onlyVideo = sp.getBoolean(Constants.ONLY_VIDEO, false)
        while (iterator.hasNext()) {
            val next = iterator.next()
            if (next.bytesSent == 0 && next.receiveByteNum == 0L) {
                iterator.remove()
                continue
            }
            if (NatSession.UDP == next.type || !next.isHttp || next.getRequestUrl() == null) {
                iterator.remove()
                continue
            }

            if (onlyVideo && !(next.getRequestUrl().contains(".ts") || next.getRequestUrl().contains("m3u8"))) {
                iterator.remove()
                continue
            }

            val appInfo = next.appInfo

            if (appInfo != null) {
                val appPackageName = appInfo!!.pkgs.getAt(0)
                if (packageName == appPackageName) {
                    iterator.remove()
                    continue
                }
                if (selectPackage != null && selectPackage != appPackageName) {
                    iterator.remove()
                }

            }
        }

        if (allNetConnection.size > 0) {
            captureList.clear()
            captureList.addAll(allNetConnection)
        }
    }

    override fun serve(session: NanoHTTPD.IHTTPSession): NanoHTTPD.Response {
        var msg = "<html><head><meta http-equiv=\"refresh\" content=\"10\"><meta charset=\"UTF-8\"><title>多乐播抓取辅助工具页面</title></head><body><h1>请求地址抓取记录</h1>\n"
        val parms = session.parms
        if (parms["clear"] != null) {

        } else {
            for (natSession in captureList) {
                msg += "<p>================================================================================="
                msg += "<p>请求时间 : " + TimeFormatUtil.formatHHMMSSMM(natSession.refreshTime)
                msg += "<p>请求地址：" + natSession.getRequestUrl()
            }
        }
        return NanoHTTPD.newFixedLengthResponse("$msg</body></html>\n")
    }
}
