import serial
import re
import time
import os
import sys

def test_ok():
    GREEN = "\033[32m"
    RESET = "\033[0m"
    print(GREEN)
    print( " #####     ##     ####    ####" )
    print( " #    #   #  #   #       #" )
    print( " #    #  #    #   ####    ####" )
    print( " #####   ######       #       #" )
    print( " #       #    #  #    #  #    #" )
    print( " #       #    #   ####    ####" )
    print(RESET)

def test_failed():
    RED = "\033[31m"
    RESET = "\033[0m"
    print(RED)
    print( " ######    ##    #  #       ######  #####" )
    print( " #        #  #   #  #       #       #    #" )
    print( " #####   #    #  #  #       #####   #    #" )
    print( " #       ######  #  #       #       #    #" )
    print( " #       #    #  #  #       #       #    #" )
    print( " #       #    #  #  ######  ######  #####" )
    print(RESET)


def isValidity(value):
    return re.match( r'([0-9]+).([0-9]*)', value)

def checkGSV(line: str) -> bool:
    state = False
    item = line.split(",")
    if item[3].isdigit() and item[5].isdigit() and item[6].isdigit():
        t_total_Sat = int(item[3])
        t_sat_elev = int(item[5])
        t_sat_az = int(item[6])
        if (t_total_Sat > 0 and t_total_Sat < 33) and (t_sat_elev >= 0 and t_sat_elev <=99) and (t_sat_az >= 0 and t_sat_az <= 359):
            return True
    return state

def checkRMC(line: str) -> bool:
    state = False
    item = line.split(",")
    if item[2] == "A" and (item[4] == "N" or item[4] == "S") and (item[6] == "E" or item[6] == "W"):
        state = True
    return state

def checkGGA(line : str) -> bool:
    state = False
    item = line.split(",")
    if item[3] == "N" or item[3] == "S":
        if isValidity(item[2]) and isValidity(item[4]):
            state = True
    return state

def read_line(ser) -> str:
    line = ser.readline()
    if line:
        return line.decode('utf-8').strip()
    return ""    

def check_gps_set():
    state = False
    print("[debug] 设置GPS 自动模式...")
    ser = serial.Serial(port='/dev/ttyUSB2',timeout=1)
    # command_0 = "AT+QGPSCFG=\"autogps\"?\r\n"
    command_1 =  "AT+QGPSCFG=\"autogps\",1\r\n"
    try:
        ser.write(command_1.encode('utf-8'))
        for i in range(300):
            line = read_line(ser)
            if line:
                print(line)
                if "ok" in line.lower():
                    state = True
                    break
            time.sleep(0.01)
    except Exception:
        print("Program terminated by user")
        state = False
    finally:
        ser.close()         
    return state

def reset_4g():
    if os.system("dpkg -l | grep -Eq \"ed-cm4(sen|ind)\"") == 0:
        print("[debug] 复位Sen/Ind 4G模块...")
        os.system("gpioset 0 10=1")
        time.sleep(0.2)
        os.system("gpioset 0 10=0")
    else:
        print("[debug] 复位IPC/HMI 4G模块...")
        os.system("gpioset $(gpiofind 4G_RST)=0")
        time.sleep(0.2)
        os.system("gpioset $(gpiofind 4G_RST)=1")
    time.sleep(0.5)
    while True:
        if os.path.exists("/dev/ttyUSB2"):
            print("[debug]4G 复位成功")
            break
        else:
            print("[debug] 等待4G复位...")
        time.sleep(1)

def start(t_tty):
    reset_4g()
    state = False
    if not check_gps_set():
        print("\033[31m配置GPS自动模式失败\033[0m")
        return state
    print(f"TTY: /dev/ttyUSB{t_tty},开始定位GPS...")
    ser = serial.Serial(port=f'/dev/ttyUSB{t_tty}',timeout=1)
    try:
        index = 0
        while True:
            index += 1
            line = read_line(ser)
            if line:
                if line.startswith("$G") and "GGA" in line:
                    if checkGGA(line):
                        print("[debug] GGA 信号检查OK")
                        state = True
                        break
                elif line.startswith("$G") and "RMC" in line:
                    if checkRMC(line):
                        print("[debug] RMC 信号检查OK")
                        state = True
                        break
            if index == 5:
                index = 0
                print("等待GPS信号...")
    except Exception as e:
        print(str(e))
        print("Program terminated by user")
    finally:
        ser.close() 
    return state

if __name__ == '__main__':
    t_tty=1
    if len(sys.argv) == 2:
        t_tty=int(sys.argv[1])
    print("[debug] 关闭冲突服务...")
    os.system("systemctl stop ModemManager.service")
    os.system("sudo systemctl stop ed-lte-tools.service")
    os.system("sudo systemctl stop ed-lte-daemon.service")
    if start(t_tty):
        test_ok()
    else:
        test_failed()
