#!/usr/bin/env python
# coding=utf-8

import os, sys, time ,re
from threading import Timer
import threading
from threading import Lock, Thread, _sleep
from logger.logrecord import LogRecord


if os.name == 'posix' and sys.version_info[0] < 3:
    import subprocess32 as subprocess
else:
    import subprocess

# LogRecord.instance().logger.debug("debug")
# LogRecord.instance().logger.info("info")
# LogRecord.instance().logger.warn("warn")
# LogRecord.instance().logger.error("erro")

usbIpDir = "/mcos/dvclient/sbin/usbip"


#####################################################

class UsbIp_Mgr(object):

    __usbSer = None
    __usbSubID = None

    __usbServerPath = "/mcos/dvclient/sbin/usbip/usbip-server" # server 路径
    __usbServerLogPath = "/mcos/dvclient/log/usbip.log"  # 日志 路径
    __usbMgrPath = "/mcos/dvclient/sbin/usbip/usbip-mgr" # usbip-mgr 路径

    __usbipMgrThread = None
    __usbipMgrThreadRun = False
    __usbipMgrThreadLock = Lock()

    __usbipConnectStatus = False  # usbip 连接状态

    __connectTimer = None

    #@classmethod
    #def __clearOldProcess(cls):
    #    """
    #    杀死原有的usbserver进程
    #    :return:
    #    """
    #    try:
    #        proc = os.popen('ps -aux | grep usbip-server')
    #        resStr = proc.read()
    #        proc.close()
    #        LogRecord.instance().logger.debug(resStr)
    #        lines = resStr.splitlines()
    #        for line in lines:
    #            if (line.find('usbip-server') >= 0):
    #                items = line.split()
    #                if len(items) > 2:
    #                    pid = items[1]
    #                    if (int(pid) != cls.__usbSubID):
    #                        LogRecord.instance().logger.debug('结束原有的usbip-server进程：'+pid)
    #                        cls.__usbSer = None
    #                        os.system('kill '+pid)

    #    except Exception,err:
    #        LogRecord.instance().logger.exception('获取usbip服务进程号异常！')

    @classmethod
    def usbIpServer_run(cls):         # 启动客户端进程
        try:
            LogRecord.instance().logger.info("start usbIp Server ... ...")
            args = [cls.__usbServerPath]
            args.append("-f")
            args.append(cls.__usbServerLogPath)
            LogRecord.instance().logger.debug(args)
            cls.__usbSer = subprocess.Popen(args,close_fds=True) # 启动
            cls.__usbSubID = cls.__usbSer.pid

            LogRecord.instance().logger.debug('cls.__usbSer::'+
                                              str(cls.__usbSer)+
                                              '\tcls.__usbSubID::'+
                                              str(cls.__usbSubID))
            #add by wangshigang for kill existing process of usbIp Server
            # cls.__clearOldProcess()

            return True
        except OSError: # 目录文件不存在
            LogRecord.instance().logger.error(cls.__usbServerLogPath + ": not fond")
            LogRecord.instance().logger.exception("usbserver run")
            return False
        except Exception:
            LogRecord.instance().logger.exception("usbserver run")
            return False

    @classmethod
    def usbIpServer_stop(cls):       # 关闭 usb ip服务
        try:
            if cls.__usbSer != None:
                cls.__usbSer.kill()
                # cls.__usbSer.wait()
                time.sleep(0.01)
                cls.__usbSer.poll()  # 避免僵尸 进程
                cls.__usbSer = None
                cls.__usbSubID = None
        except Exception as e:
            LogRecord.instance().logger.exception("usbserver stop")
            raise e

    @classmethod
    def getUsbIpThread(cls):
        UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
        __thread = UsbIp_Mgr.__usbipMgrThread
        UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁
        return __thread

    # 停止 usbip连接
    @classmethod
    def usbIpConnect_Stop(cls):
        try:
            UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
            cls.__usbIpThread_Stop()  #
        finally:
            UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁

    @classmethod
    def __usbIpThread_Stop(cls):
        try:
            if cls.__usbipMgrThread != None:
                if cls.__usbipMgrThread.isAlive():
                    cls.__usbipMgrThreadRun = False  # 停止 线程
                    cls.__usbipMgrThread.join(1)  # 等待 线程停止  <= 0.01 ms
                    LogRecord.instance().logger.info("usbIpThread stop")

                del cls.__usbipMgrThread  # 释放

        finally:
            cls.__usbipMgrThread = None

    # =========== 启动 usbip连接线程 ===============
    # 参数 :ip,     windows 端 的 ip地址
    #     : times    发起连接,持续 最长时间,秒
    # ---------------------------------------------
    @classmethod
    def __usbIpThread_Run(cls, ip_list, times=60):
        # print "usbipThread_Run"
        UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
        try:
            # 1. 停止 线程
            cls.__usbIpThread_Stop()  # 停止 线程

            if cls.__usbipMgrThread == None:

                #=======================================================
                def func(ip_list, times):
                    while times > 0:      #控制 连接 次数
                        times = times - 1

                        # -------------- 遍历 ip列表 连接 -------------------
                        for i in range(len(ip_list)):
                            cls.__usbipConnectStatus = cls.usb_connect(ip_list[i])

                            if cls.__usbipConnectStatus == 0:  # 如果 连接成功 立即 结束 连接
                                LogRecord.instance().logger.info("usbip connect seccess:" + str(ip_list[i]))

                                return None

                            info = "usbip connect Fail: [%s], %sth -- %s" % \
                                   (str(ip_list[i]), str(times), str(cls.__usbipConnectStatus))
                            LogRecord.instance().logger.info(info)

                        #----------- 延时 1秒 -------------
                        for i in range(10):   # 延时 1秒
                            if cls.__usbipMgrThreadRun == False:  # 如果 线程 停止
                                # print "thread stop ----"
                                LogRecord.instance().logger.info("usbipMgr ThreadStop")
                                return None
                            _sleep(0.1)

                        if cls.__usbipConnectStatus == 25600:
                            try:
                                LogRecord.instance().logger.error("usbip-server died!")
                                # cls.usbIpServer_stop()
                                cls.usbIpServer_run()
                            except Exception,err:
                                LogRecord.instance().logger.exception("restart usbip-server exception!")


                    # sys.stdout.flush()
                    cls.__usbipMgrThreadRun = False  # 如果 线程 线程 执行 结束
                #===========================================================

                cls.__usbipMgrThread = Thread(target=func, args=(ip_list, times))  # 初始化接收线程
                cls.__usbipMgrThread.setDaemon(True)  # 设置 Daemon


            # 2. 启动连接线程
            cls.__usbipMgrThreadRun = True  # 如果 线程
            cls.__usbipMgrThread.start()  #

        except Exception as e:
            LogRecord.instance().logger.exception("usbip thread run")
            raise e
        finally:
            UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁


    # 发起 usbip 连接  已经 弃用
    @classmethod
    def usb_connect(cls, ip=None):
        if ip == None:
            return None

        cls.usb_disconnect()  # 断开　usbip 连接
        cmd = cls.__usbMgrPath + " -c  " + str(ip)
        LogRecord.instance().logger.debug(cmd)
        status = os.system(cmd)
        return status


    # 发起 usbip 连接  已经 弃用
    @classmethod
    def usb_connect_once(cls, ip=None):
        if ip == None:
            return None

        cls.usb_disconnect()  # 断开　usbip 连接
        # cmd = cls.__usbMgrPath + " -c  " + str(ip)
        # LogRecord.instance().logger.debug(cmd)

        args = [cls.__usbMgrPath,"-c",str(ip)]
        status = subprocess.call(args)
        # status = subprocess.call(["/mcos/dvclient/sbin/usbip/usbip-mgr","-c","192.168.8.88"])
        # status = os.system(cmd)
        return status


    # 断开 usbip 连接
    @classmethod
    def usb_disconnect(cls):
        os.system(cls.__usbMgrPath + "  -d")  # 断开 连接

    # 发起 usbip 连接 2  已经弃用
    @classmethod
    def usb_connect2(cls, ip=None, times=15 * 60):
        if ip == None:
            return False
        ip_list = ip
        cls.__usbIpThread_Run(ip_list, times)  # 15 分钟
        return True


    # 发起 usbip 连接  # 扩展
    @classmethod
    def usb_connect_Ext(cls, ip_list=None, times=15 * 60):
        if ip_list == None or type(ip_list) != type([]):
            return False
        cls.__usbIpThread_Run(ip_list,times) # 15 分钟
        return True

    #timer单次建立连接
    @classmethod
    def __one_connect(cls,iplist):
        if type(iplist) != list:
            LogRecord.instance().logger.error("connect usb, iplist in error type!")
            return False
        for ip in iplist:
            status = cls.usb_connect(str(ip))
            if status == 0:
                LogRecord.instance().logger.debug("connect usb use ip:"+ip+" success!")
                cls.__connectTimer.cancel()
                return True
            elif status == 25600:
                LogRecord.instance().logger.debug("connect usb, usbip-server died!")
                cls.__connectTimer.cancel()
                cls.usbIpServer_run()
                return False
            else:
                LogRecord.instance().logger.info("connect usb, fail number:"+str(status))
        return False

    #连新的usbip连接函数，使用timer
    @classmethod
    def usb_connect3(cls,ip = None, interval =3.0):
        if ip == None:
            LogRecord.instance().logger.error("connect usb, with empty ip!")
            return False
        if type(ip) != list:
            LogRecord.instance().logger.error("connect usb, ip list in error type!")
            return False
        try:
            if cls.__connectTimer != None:
                LogRecord.instance().logger.debug("cancel last connect usb!")
                cls.__connectTimer.cancel()
                cls.__connectTimer = None

            cls.__connectTimer = Timer(interval=interval,
                                       function=cls.__one_connect,
                                       args=[ip])
            cls.__connectTimer.start()
        except Exception,err:
            LogRecord.instance().logger.exception("connect usbip exception!")
            return False
    #停止usbip连接timer
    @classmethod
    def usb_connect3_stop(cls):
        try:
            cls.__connectTimer.cancel()
        except Exception,err:
            LogRecord.instance().logger.exception("disconnect usbip exception!")

    # #判断是否连接某个ip
    # @classmethod
    # def is_connect_ip(cls,ip):
    #     if not isinstance(ip,str):
    #         LogRecord.instance().logger.warn("用来检测usbip连接的ip的格式错误！"+str(type(ip)))
    #         return False
    #     elif ip == '':
    #         LogRecord.instance().logger.warn("用来检测usbip连接的ip为空！")
    #         return False
    #     try:
    #         cmd = 'sudo '+cls.__usbMgrPath + " -s "
    #         proc = os.popen(cmd)
    #         resStr = proc.read()
    #         proc.close()
    #         LogRecord.instance().logger.debug(resStr)
    #         if resStr.find('disactive') >= 0:
    #             LogRecord.instance().logger.debug('usbip没有连接！')
    #             return False
    #         elif resStr.find(ip.strip()):
    #             return True
    #         else:
    #             LogRecord.instance().logger.error('usbip连接状态未知！')
    #             return False
    #     except Exception,err:
    #         LogRecord.instance().logger.exception("检测usubip连接状态异常！")
    #         return False

    #判断是否连接某个ip
    @classmethod
    def get_connected_ip(cls):
        ipReg=re.compile('(\[((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-4])\]){1}')

        try:
            cmd = 'sudo '+cls.__usbMgrPath + " -s "
            proc = os.popen(cmd)
            resStr = proc.read()
            proc.close()
            LogRecord.instance().logger.debug(resStr)
            if resStr.find('disactive') >= 0:
                LogRecord.instance().logger.debug('usbip没有连接！')
                return None
            else:
                search_ret = ipReg.search(resStr)
                if search_ret == None:
                    LogRecord.instance().logger.error('usbip连接状态错误！')
                    return None
                ipStr = search_ret.groups()[0]
                if len(ipStr) < 9:
                    LogRecord.instance().logger.error('检测usbip连接状态,返回的ip格式错误！！')
                    return None
                conIP = ipStr[1:-1]
                return conIP
        except Exception,err:
            LogRecord.instance().logger.exception("检测usubip连接状态异常！")
            return None


################# 测试用例  ######################3

def test_main2():
    # UsbIp_Mgr.usb_connect2("192.168.102.201")
    UsbIp_Mgr.usb_connect3([u"192.168.102.100"])

def test_main3():
    status = UsbIp_Mgr.usb_connect_once(u"192.168.102.106")
    print "",status


if __name__ == "__main__":
    from os import getenv, environ

    if getenv('LOG_STDOUT') == None:
        environ["LOG_STDOUT"] = "stdout"  #

    test_main3()
    # time.sleep(4)
    # UsbIp_Mgr.usbIpConnect_Stop()
