package com.gh.gamecenter.vpn

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.ParcelFileDescriptor
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.activityresult.ActResultRequest
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IVpnProvider
import java.util.HashSet

@Route(path = RouteConsts.provider.vpn, name = "VPN 暴露服务")
class VpnProviderImpl : IVpnProvider {

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun isVpnPermissionGranted(activity: AppCompatActivity): Boolean {
        return (HaloVpnService.prepare(activity) == null)
    }

    /**
     * @param packageNameSet 要应用 VPN 的包名列表
     * @param vpnStartedCallback 启动 VPN 的回调，值为 true 代表遇到错误
     */
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun startVpn(
        activity: AppCompatActivity,
        packageNameSet: HashSet<String>,
        vpnStartedCallback: ((containsError: Boolean) -> Unit),
        pfdCreatedCallback: ((pfd: ParcelFileDescriptor?) -> Unit)
    ) {
        val intent = HaloVpnService.prepare(activity)
        if (intent != null) {
            try {
                ActResultRequest(activity).startForResult(intent) { resultCode, _ ->
                    if (resultCode == Activity.RESULT_OK) {
                        pfdCreatedCallback.invoke(startVpn(activity, packageNameSet))
                        vpnStartedCallback.invoke(false)
                    } else if (resultCode == Activity.RESULT_CANCELED) {
                        vpnStartedCallback.invoke(false)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                pfdCreatedCallback.invoke(null)
                vpnStartedCallback.invoke(true)
            }
        } else {
            pfdCreatedCallback.invoke(startVpn(activity, packageNameSet))
            vpnStartedCallback.invoke(false)
        }
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    private fun startVpn(
        activity: AppCompatActivity,
        packageNameSet: HashSet<String>,
    ): ParcelFileDescriptor? {
        val pfd: ParcelFileDescriptor? = HaloVpnService.startVPN(packageNameSet)
        val serviceIntent = Intent(activity, HaloVpnService::class.java)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            activity.startForegroundService(serviceIntent)
        } else {
            activity.startService(serviceIntent)
        }

        return pfd
    }

    override fun stopVpn(context: Context, pfd: ParcelFileDescriptor?) {
        val intent = Intent(context, HaloVpnService::class.java)
        intent.putExtra(HaloVpnService.KEY_ACTION_TYPE, HaloVpnService.ACTION_STOP)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intent)
        } else {
            context.startService(intent)
        }
        HaloVpnService.stopVPN(pfd!!)
    }

    override fun init(context: Context?) {
        // do nothing
    }

}