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

# ----------------------------------------------------------------------------------
# 相关文档请参考:
#   http://192.168.1.22/mcos-linux-client-doc/linux-client-v4-5-doc/blob/master/usbip.md
# ----------------------------------------------------------------------------------

import commands
import os, sys
from threading import Lock
from time import sleep

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


class UsbIp_Mgr(object):

    __usbSer = None
    __usbIpLogProcess = None

    __usbipMgrThreadLock = Lock()


    # ********************************
    #   名称: 启动usbip 日志处理服务　
    # 　参数：
    #        字符串 LOGPATH : 指定 日志路径
    #   返回：　
    #       int   0  : 成功
    #       int   -1 :  log.sh 不存在
    # ********************************
    @classmethod
    def usbIpLogProcess_run(cls,LOGPATH="usbip.log"):         # 启动usbip-日志处理

        try:
            UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
            args = ["log.sh"]
            cls.__usbIpLogProcess = subprocess.Popen(args,close_fds=True) # 启动
            return  0
        except OSError: # 目录文件不存在
            return -1
        finally:
            UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁

    # ********************************
    #   名称: 关闭usbip 日志处理服务
    # 　参数：
    #         无
    #   返回：　
    #       int   0  : 成功
    # ********************************
    @classmethod
    def usbIpLogProcess_stop(cls):       # 关闭 usb ip服务
        try:
            UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
            if cls.__usbIpLogProcess != None:
                cls.__usbIpLogProcess.kill()
                cls.__usbIpLogProcess.wait()   # 等待资源释放
                cls.__usbIpLogProcess = None
            return 0
        except Exception as e:
            raise e
        finally:
            UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁


    # ********************************
    #   名称: 启动usbip　Server
    # 　参数：
    #        字符串 LOGPATH : 指定 日志路径
    #   返回：　
    #       int   0  : 成功
    #       int   -1 :  usbip-server 不存在
    # ********************************
    @classmethod
    def usbIpServer_run(cls,LOGPATH="usbip.log"):         # 启动usbip-server

        try:
            UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
            args = ["usbip-server"]
            args.append("-f")
            args.append(LOGPATH)           # 指定 日志 路径
            cls.__usbSer = subprocess.Popen(args,close_fds=True) # 启动
            # sleep(0.01)
            return  0
        except OSError: # 目录文件不存在
            return -1
        finally:
            UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁

    # ********************************
    #   名称: 关闭usbip　Server
    # 　参数：
    #         无
    #   返回：　
    #       int   0  : 成功
    # ********************************
    @classmethod
    def usbIpServer_stop(cls):       # 关闭 usb ip服务
        try:
            UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
            if cls.__usbSer != None:
                cls.__usbSer.kill()
                # sleep(0.01)
                # cls.__usbSer.poll() # 防止僵尸 进程产生
                cls.__usbSer.wait()   # 等待资源释放
                cls.__usbSer = None
            return 0
        except Exception as e:
            raise e
        finally:
            UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁


    # ********************************
    #   名称:  检查usb server 是否运行, 释放僵尸进程
    # 　参数：
    #         无
    #   返回：　
    #       int   0  :  运行中
    #       int   -1 : 没启动
    #       int   -2 : 没运行
    # ********************************
    @classmethod
    def usbIpServer_check(cls):       # 关闭 usb ip服务
        try:
            UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
            if cls.__usbSer == None:
                return -1
            if cls.__usbSer.poll() == None: #
                return 0     # usbserver进程正在运行
            else:
                return -1
        except Exception as e:
            raise e
        finally:
            UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁

    # ****************************************
    #  名称　： 发起 usbip 连接
    #
    #  返回:
    #     int  0  ：　成功
    #     int 100 : usbip-server没有启动
    #     int 200 : windows客户端连接失败
    #     其他非0值 : 其他错误
    # ***************************************
    @classmethod
    def usb_connect(cls, ip):
        try:
            from common import common_run
            if common_run.usb_status == "network_ip":
                UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
                args = ["usbip-mgr", "-c", str(ip)]
                status = subprocess.call(args)
                return status
        finally:
            from common import common_run
            if common_run.usb_status == "network_ip":
                UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁

    # ****************************************
    #  名称　： 断开 usbip 连接
    #
    #  返回:
    #     int  0  ：　成功
    #     int 100 : usbip-server没有启动
    #     int 200 : windows客户端连接失败
    #     其他非0值 : 其他错误
    # ***************************************
    @classmethod
    def usb_disconnect(cls):
        try:
            UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
            status = subprocess.call(["usbip-mgr", "-d"])
            return status
        finally:
            UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁

    # *************************
    # 名称　  :　判断连接状态
    # 返回：
    #     int  0  : 连接中
    #     非0值　　: 未连接
    # *************************
    @classmethod
    def usb_CheckStatus(cls):
        try:
            UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
            ret = commands.getstatusoutput("usbip-mgr  -s")
            if str(ret[0]) == "0":
                if str(ret[1]).find(": active") >= 0:
                    return 0
            return -1
        finally:
            UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁

    #************************************************
    # 名称:　获取当前连接　ip地址
    #
    # 返回:
    #   　　成功 字符串：　　返回当前连接 ip   编码格式  {'confidence': 1.0, 'encoding': 'ascii'}
    #      失败 返回 ""
    #***********************************************
    @classmethod
    def usb_getConnectIP(cls):
        try:
            UsbIp_Mgr.__usbipMgrThreadLock.acquire(True)  # 请求锁
            ret = commands.getstatusoutput("usbip-mgr  -s")
            if str(ret[0]) == "0":
                ip = ""
                tmplist = str(ret[1]).split("server IP [")
                print tmplist
                if len(tmplist) > 1:
                    ip = tmplist[1].strip("]")
                # 实现 查找 ip
                return  ip
            return  ""
        finally:
            UsbIp_Mgr.__usbipMgrThreadLock.release()  # 释放锁

    #***********************************
    # 名  称:    usbip连接口
    # 参　数:    ip 列表：　　如　["192.168.102.1","192.168.102.2",....]
    # 返回值:
    #    元组  (status,ip)
    #    status:
    #    int    0  :   成功
    #    int   100 :   usb-server 未启动
    #    int   -1  : 　ip_list 为空
    #    其他数值   ：　 其他错误
    #***********************************
    @classmethod
    def usb_connect_guestAddres(cls,ip_list):
        if type(ip_list) != list:
            raise Exception("argument err: ip_list") # 参数异常

        cls.usb_disconnect() # 断开连接
        for ip in ip_list:
            status = cls.usb_connect(str(ip))
            if status == 0:       # 成功
                return (status,ip)
            elif status == 100:
                return (status,"") # 失败
        return (-1,"")


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

def test_main2():
    import time
    time.sleep(0.1)
    print UsbIp_Mgr.usb_connect_guestAddres(["192.168.102.11","192.168.102.12"])
    # print UsbIp_Mgr.usb_connect_guestAddres({"abc":12})  # 参数异常
    # usb ip 连接测试
    status = UsbIp_Mgr.usb_connect("192.168.102.118")
    if status == 0:
        print "usbip连接 成功 ", status
    elif status == 100:
        print "usbip连接 : usbip-server 未启动 ", status
    elif status == 200:
        print "usbip连接 : 连接windows客户端失败 ", status
    else:
        print "usbip连接 : 失败 ", status

    status =  UsbIp_Mgr.usb_CheckStatus()
    print "usbip连接状态:", status


def test_main3():
    ip = UsbIp_Mgr.usb_getConnectIP()
    print "ip = [%s]"%ip, type(ip)
    import chardet
    print "编码: ", chardet.detect(ip)
    UsbIp_Mgr.usb_disconnect()

if __name__ == "__main__":
    import os
    from os import getenv, environ
    environ["PATH"] = "/mcos/dvclient/sbin/usbip/:" + getenv("PATH")

    # UsbIp_Mgr.usbIpServer_run("/mcos/dvclient/log/usbip.log")
    os.system("usbip-server -f /tmp/usbip.log")

    # test_main2()
    # test_main3()
    # UsbIp_Mgr.usbIpServer_stop()

    sleep(60)
