package zs.qimai.com.printer2.manager

import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import com.tools.io.EthernetPort
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import zs.qimai.com.printer2.utils.PrintFormat
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.net.*
import java.util.*

/**
 * <pre>
 *     author : leiwang
 *     e-mail : xxx@xx
 *     time   : 2021/03/18
 *     desc   :
 *     version: 1.0
 * </pre>
 */
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
class EthernetPort {
    private var mSocket: Socket? = null
    private var mInetAddress: InetAddress? = null
    private var mIp: String? = null
    private var mPort = 0
    private var mSocketAddress: SocketAddress? = null
    private var connSuccessful = false
    private val connState = false
    var inputStream: InputStream? = null
    var outputStream: OutputStream? = null
    var mHandler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
           // goToListener()
        }
    }

    constructor(ip: String?, port: Int) {
        mIp = ip
        mPort = port
    }

    constructor() {}

    fun setIp(ip: String?) {
        mIp = ip
    }

    fun setPort(port: Int) {
        mPort = port
    }

    @Throws(IOException::class)
    private fun initSocketStream() {
        inputStream = mSocket!!.getInputStream()
        outputStream = mSocket!!.getOutputStream()
    }

    fun openPort(): Boolean {
        val thread: Thread = object : Thread() {
            override fun run() {
                mSocket = Socket()
                try {
                    mInetAddress = Inet4Address.getByName(mIp)
                    mSocketAddress = InetSocketAddress(mInetAddress, mPort)
                    mSocket!!.connect(mSocketAddress, 4000)
                    initSocketStream()
                    connSuccessful = true
                    //发送监听
                    mHandler.sendEmptyMessage(0)
                } catch (var4: UnknownHostException) {
                    //    Log.e(EthernetPort.Companion.TAG, "IpAddress is invalid", var4)
                    connSuccessful = false
                } catch (var5: IOException) {
                    connSuccessful = false
                    //  Log.e(EthernetPort.Companion.TAG, "connect failed", var5)
                    try {
                        if (mSocket != null) {
                            mSocket!!.close()
                        }
                    } catch (var3: IOException) {/*
                        Log.e(
                            EthernetPort.Companion.TAG,
                            "unable to close() socket during connection failure",
                            var3
                        )*/
                    }
                }
            }
        }
        thread.start()
        try {
            thread.join()
        } catch (var3: InterruptedException) {
            var3.printStackTrace()
        }
        return connSuccessful
    }

    private fun goToListener() {
        GlobalScope.launch(Dispatchers.IO) {
            //when (true) {
            try {
                // Log.d(TAG, "goToListener: begin")
                // outputStream!!.write(PrintFormat.INITBYTE)
                //  val input =  mSocket?.getInputStream()?.read()
                mIp?.let {
                    val status = startPing(it)
                    if (status) {
                        mHandler.sendEmptyMessageDelayed(9, 10000)
                    } else {
                        //移除设备
                       removeDevice(it)
                        Log.d(TAG, "goToListener: socket disconnect")
                    }
                }

            } catch (e: SocketException) {
                Log.d(TAG, "run: disconnect e= ${e.message}")

            } catch (e: IOException) {
                Log.d(TAG, "run: disconnect e= ${e.message}")
            }
        }
        //      }
    }

    private fun startPing(ip: String): Boolean {
        Log.e("Ping", "startPing...")
        var success = false
        var p: Process? = null
        try {
            //其中 -c 1为发送的次数，1为表示发送1次，-w 表示发送后等待响应的时间。
            p = Runtime.getRuntime().exec("ping -c 5 -i 2 -W 2 $ip")
            val status = p.waitFor()
            success = if (status == 0) {
                true
            } else {
                false
            }
        } catch (e: IOException) {
            success = false
        } catch (e: InterruptedException) {
            success = false
        } finally {
            p!!.destroy()
        }
        return success
    }

    @Throws(IOException::class)
    fun writeDataImmediately(data: Vector<Byte>) {
        this.writeDataImmediately(data, 0, data.size)
    }

    @Throws(IOException::class)
    fun writeDataImmediately(data: Vector<Byte>, offset: Int, len: Int) {
        object : Thread() {
            override fun run() {
                try {
                    if (mSocket != null && outputStream != null && data.size > 0) {
                        outputStream?.write(convertVectorByteToBytes(data), offset, len)
                        outputStream?.flush()
                    }
                } catch (var2: IOException) {
                    /*   Log.e(
                           EthernetPort.Companion.TAG,
                           "EthernetPort.class writeDataImmediately method error!",
                           var2
                       )*/
                }
            }
        }.start()
    }

    fun readData(bytes: ByteArray): Int {
        return if (inputStream == null) {
            -1
        } else
            if (inputStream?.available()!! > 0) inputStream!!.read(bytes) else 0

    }

    fun closePort(): Boolean {
        return try {
            closeStreamAndSocket()
            true
        } catch (var2: IOException) {
            //Log.e(EthernetPort.Companion.TAG, "Close port error!", var2)
            false
        }
    }

    @Throws(IOException::class)
    private fun closeStreamAndSocket() {
        if (outputStream != null) {
            outputStream?.close()
            outputStream = null
        }
        if (inputStream != null) {
            inputStream?.close()
            inputStream = null
        }
        if (mSocket != null) {
            mSocket!!.close()
            mSocket = null
        }
    }

    companion object {
        private val TAG = EthernetPort::class.java.simpleName
    }

    protected fun convertVectorByteToBytes(data: Vector<Byte>): ByteArray? {
        val sendData = ByteArray(data.size)
        if (data.size > 0) {
            for (i in data.indices) {
                sendData[i] = data[i] as Byte
            }
        }
        return sendData
    }

    //移除设备
    fun removeDevice(deviceId: String) {
        DeviceManagerUtils.getInstance().getDeviceAccordDeviceId(deviceId!!)
            ?.let { it1 ->
                DeviceManagerUtils.getInstance().removeDevice(
                    it1
                )
            }
        closePort()
    }
}