package com.gh.gamecenter.vpn

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.VpnService
import android.os.Build
import android.os.ParcelFileDescriptor
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import com.lightgame.R
import com.lightgame.download.ForegroundNotificationManager
import com.lightgame.utils.Utils
import java.io.IOException
import java.util.*

class HaloVpnService : VpnService() {

    private var mForegroundNotificationManager: ForegroundNotificationManager? = null

    override fun onCreate() {
        super.onCreate()

        mForegroundNotificationManager = ForegroundNotificationManager(this, this.application)
        startForegroundIfNeeded()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val serviceAction = intent?.getStringExtra(KEY_ACTION_TYPE)

        if (serviceAction == ACTION_STOP) {
            mForegroundNotificationManager?.cancel(FOREGROUND_ID)
            stopSelf()
        }

        // 不需要 intent 为空的重建
        return START_NOT_STICKY
    }

    private fun startForegroundIfNeeded() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel("VPN", "Halo VPN", NotificationManager.IMPORTANCE_LOW)
            val manager = applicationContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
            manager.createNotificationChannel(channel)
            val notification = NotificationCompat.Builder(this, "VPN")
                .setSmallIcon(R.drawable.ic_download_notification)
                .build()
            if (mForegroundNotificationManager != null) {
                mForegroundNotificationManager?.notify(FOREGROUND_ID, notification)
            }
        }
    }

    companion object {

        const val KEY_ACTION_TYPE = "action_type"
        const val ACTION_STOP = "stop"
        const val FOREGROUND_ID = 1011

        @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
        fun prepare(context: Context): Intent? {
            return VpnService.prepare(context)
        }

        @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
        fun startVPN(noInternetConnectionPackageNameSet: HashSet<String>): ParcelFileDescriptor? {
            val builder = HaloVpnService().Builder()
            builder.addAddress("10.1.10.1", 32)
            builder.addAddress("fd00:1:fd00:1:fd00:1:fd00:1", 128)
            builder.setMtu(10000)
            builder.addRoute("0.0.0.0", 0)
            builder.addRoute("2000::", 3)

            for (packageName in noInternetConnectionPackageNameSet) {
                try {
                    builder.addAllowedApplication(packageName)
                } catch (e: PackageManager.NameNotFoundException) {
                    e.printStackTrace()
                }
            }

            return builder.establish()
        }

        fun stopVPN(pfd: ParcelFileDescriptor) {
            try {
                pfd.close()
            } catch(e: IOException) {
                Utils.log("VPN", "encounter error while trying to stop VPN, ${e.localizedMessage}")
            }
        }

    }

}