#coding:utf-8
import os
import subprocess
import sqlite3
import argparse
import re
from time import sleep
import signal

if __name__ != "__main__":
    exit(0)

class MyError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)
    
def checkping(addr):
    strcmd = "ping %s -w 2" % addr
    ret = subprocess.Popen(strcmd, shell=True, stdout = subprocess.PIPE)
    str_b = ret.stdout.read()
    strback = bytes.decode(str_b)
    for item in strback.split(" "):
        if "time=" in item:
            strftime = item[item.find("=") + 1:]
            ftime = float(strftime)
            if ftime != 0:
                return "connected"
                break
    return "disconnect"
    
def relineEth(strname, serverip):
    try:    
        strcmd = "ifconfig %s" % strname
        ret = subprocess.Popen(strcmd, shell=True, stdout = subprocess.PIPE)
        str_b = ret.stdout.read()
        strback = bytes.decode(str_b)
    
        result = re.findall(".*\n.*inet\s\D+:(\d+.\d+.\d+.\d+).*",strback)
        if len(result) == 0:
            raise MyError("no find ip by card")
        fr = open("/etc/network/interfaces", "r")
        facesstrall = fr.read(1000)
        #获取处理网关
        right = "auto\s+%s.*(\s.*){4}gateway\s(\d+.\d+.\d+.\d+).*" % strname
        route = re.findall(right, facesstrall)
        itemroute = "null"
        if len(route) != 0:
            if len(route[0]) == 2:
                itemroute = route[0][1]
        itemroute = "%s" % itemroute
        if itemroute == "null":
            raise MyError("no such 'eth' route")
        
        ip = result[0]
        os.system("ifconfig %s up" % (strname))
        os.system("ifconfig %s %s" % (strname, ip))
        os.system("/etc/init.d/networking restart")
        os.system("route add default gw %s" % itemroute)
        
        sleep(5)
        
        ret = checkping(serverip)
        return ret
    except MyError as contain :
        print(contain.value)
        exit(0)
    except IndexError:
        print("list index out of range")
        exit(0)
    
def relineWlan(strname, serverip = "192.168.1.1"):
    try:
        ret = subprocess.Popen("ps -a", shell=True, stdout = subprocess.PIPE)
        str_b = ret.stdout.read()
        strback = bytes.decode(str_b)
        
        for item in strback.split("\n"):
            if "wpa_supplicant" in item:
                os.system("killall wpa_supplicant")
            elif "dhclient" in item:
                os.system("killall dhclient")
        
        #去除其他同网段的网卡
        ret = subprocess.Popen("ifconfig", shell=True, stdout = subprocess.PIPE)
        str_b = ret.stdout.read()
        strback = bytes.decode(str_b)
        dictcard = {}
        for item in strback.split("\n\n"):
            result = re.findall("(\S+)\s+Link.*\n\s+inet\s\S+:(\d+.\d+.\d+.\d+).*", item)
            if len(result) != 0:
                listcardinfo = list(result[0])
                if len(listcardinfo) == 2:
                    dictcard[listcardinfo[0]] = listcardinfo[1]
        if strname not in dictcard.keys():
            os.system("ifconfig %s up" % (strname))
        else:
            usewlanip = dictcard[strname]
            for item in dictcard.keys():
                if item != strname and dictcard[item] == usewlanip:
                    os.system("ifconfig %s down" % (item))
        
        os.system("wpa_supplicant -i%s -Dwext -c /etc/wpa_supplicant/wlanpwd.conf &" % strname)
        os.system("dhclient %s &" % strname)
        
        sleep(10)
  
        ret = checkping(serverip)
        return ret
        
    except IndexError:
        print("list index out of range")
        exit(0)
    except KeyError:
        print("use card name have no find card in system")
        exit(0) 
        
def time_out(a, b):
    raise RuntimeError()        
        
def parseNoSend():
    try:
        f1 = open("./cnt_net/nosend", "r+", newline='')
        strall = f1.read()
        f1.close()
      
        #生成字典
        result = re.findall("\r\n(\d+)\r\n(^POST.*\r\n(.*\r\n){1,6}\r\n(\w+.*\n|^\{\s{1}(\t{1,}.{1,}\s{1})+^\}))", strall, re.M)
        listinfo = list(result)
        dictinfo = {}   #所有内容的字典
        for item in listinfo:
            dictinfo[item[0]] = item[1]        
        #排序
        Listkey = list(dictinfo.keys())
        Listkey.sort(reverse=True)
        #去重及去除可替代项
        newdict = {}
        for item in Listkey:
            value = dictinfo[item]
            if value not in list(newdict.keys()):
                result = re.findall("\s+SessionId:\s+(\d{1,2})", value, re.M)
                infotype = result[0]
                if infotype == "3" or infotype == "14" or infotype == "16" or infotype == "15": #删除
                    continue
                elif infotype == "2" or infotype == "7":    #可以不重新发送
                    listtype = list(newdict.values())
                    if infotype in listtype:
                        continue
                newdict[value] = infotype;        
        #创建解析好的文件
        f = open("./cnt_net/chknosend", "w+", newline='')
        listvalue = list(newdict.keys())
        for item in listvalue:
            strbuf = "%s" % item
            strbuf += "\ncls_chkfile\n"
            strbuf.encode(encoding='utf_8')
            f.write(strbuf)
        f.close()
    except FileNotFoundError:
        print("have not nosend")
    finally:
        os.system("rm -f ./cnt_net/nosend")

#-----------------------------------------------------main-------------------------------------------------------
parser = argparse.ArgumentParser(description="yes or no to close netclient, ,please enter -close")
parser.add_argument('-close', type=bool, help="close netclient")
args = parser.parse_args()
isCloseNet = args.close

#获取进程列表
ret = subprocess.Popen("ps -a", shell=True, stdout = subprocess.PIPE)
str_b = ret.stdout.read()
str_cmd = bytes.decode(str_b)

#判断是否已经启动netclient，有进程时清除占用
listprocess = str_cmd.split("\n")
for item in listprocess:
    if "NetClient2" in item:
        os.system("killall NetClient2")
        
#输入参数：-close时关闭编码进程
if isCloseNet:
    print(isCloseNet)
    exit(0)
    
#获取主程序联网设置
paramsql = sqlite3.connect("./PARAM.db")
paramcurs = paramsql.cursor()
try:
    #判断是否有需求联网
    isUseNetAll = "0"
    cursor_use = paramcurs.execute("select value from sysparam where name='CntNet'")
    for row in cursor_use:
        isUseNetAll = "%s" % row[0]
    strisusenet = "%s" % isUseNetAll[0]
    if strisusenet == "0":
        raise MyError("no need use net")
    #判断联网网卡名称
    cardname = "null"
    cursor_name = paramcurs.execute("select value from sysparam where name='CntNet_UseName'")
    for row in cursor_name:
        cardname = "%s" % row[0]
    if cardname == "null":
        raise MyError("get card name error")
    else:
        f = open("/proc/net/dev", "r")
        str_cmd = f.read()
        f.close()
        listproc_cardname = re.findall("(\S+):", str_cmd)
        if cardname not in listproc_cardname:
            raise MyError("db saved card not in /proc")
except sqlite3.OperationalError:
    print("cls：can not find sqlitefile param")
    exit(0)
except MyError as contains:
    print(contains.value)
    exit(0)
except IndexError:
    print("cls:find item out rang")
    exit(0)
finally:
    paramsql.close()

#获取服务器连接
sql = sqlite3.connect("./cnt_net/sysconf.db")
curs = sql.cursor()
try:
    #控制本函数执行的时间20s
    signal.signal(signal.SIGALRM, time_out)
    signal.setitimer(signal.ITIMER_REAL, 20, 0)

    apppath = "null"
    infopath = "null"
    addrpath = "null"
    cursor_app = curs.execute("SELECT 值 from info_sysconf where 信息名称='apppath_send'")
    for row in cursor_app:
        apppath = row[0]
    cursor_info = curs.execute("SELECT 值 from info_sysconf where 信息名称='thispath'")
    for rows in cursor_info:
        infopath = rows[0]
    cursor_addr = curs.execute("SELECT 值 from info_sysconf where 信息名称='serverip_info'")
    for rowss in cursor_addr:
        addrpath = rowss[0]
    if apppath == "null" or infopath == "null" or addrpath == "null":
        raise MyError("no such db value")
    
    #测试网络连接
    ret = checkping(addrpath)
    isThrough = False
    if ret == "disconnect" and "wlan" in cardname:
        isThrough = relineWlan(cardname, addrpath)
    elif ret == "disconnect":
        isThrough = relineEth(cardname, addrpath)
    elif ret == "connected":
        isThrough = ret
    print("reline result %s" % isThrough)

    if isThrough == "connected":
        #parseNoSend()  //取消检索9.27
        cmd = apppath + " " + infopath + " &"
        os.system(cmd)
except sqlite3.OperationalError:
    print("cls：can not find sqlitefile sysconf")
except NameError:
    print("cls：can not find item by db")
except MyError as contain:
    print(contain.value)
    exit(0)
except RuntimeError:
    print("time out to run reset")
    exit(0)
finally:
    sql.close()


