#!python
# -*- coding: utf-8 -*-
import argparse
import tempfile
import shlex
import signal
from proxyUtil import *

ch = logging.StreamHandler()
ch.setFormatter(CustomFormatter())
logging.basicConfig(level=logging.INFO, handlers=[ch])

CORE = "xray"
tempdir = tempfile.mkdtemp()

def ss_runner(ss_url, localPort):
    cmd = ssURI2sslocal(ss_url, localPort)
    logging.info(f"Running {cmd}")
    try:
        #os.execv('/bin/sh', shlex.split(cmd)) 
        p = subprocess.Popen([cmd], stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        logging.info("KeyboardInterrupt")
        os.killpg(os.getpgid(p.pid), signal.SIGTERM)  # Send the signal to all the process groups
        time.sleep(1)    # sleep 1 seconds
    except:
        logging.error(f"ss-local failed to start")
    return


def v2ray_runner(url, localPort):
    configName = createConfig(url, localPort, tempdir)
    if configName is None :
        return

    cmd = f"{CORE} run -config {configName}" 
    logging.info(f"Running {cmd}")
    try:
        p = subprocess.Popen([cmd], stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        logging.info("KeyboardInterrupt")
        #p.kill()
        #p.send_signal(signal.SIGINT)
        os.killpg(os.getpgid(p.pid), signal.SIGTERM)  # Send the signal to all the process groups
        time.sleep(1)    # sleep 1 seconds
    except:
        logging.error(f"{CORE} failed to start")
    return


def main():
    parser = argparse.ArgumentParser(description="Simple proxy client for ss/v2ray/trojan")
    parser.add_argument("link", help="proxy link")
    parser.add_argument("-l", "--lport", help="start local port, default is 1080", default=1080, type=int)
    parser.add_argument('-c', '--core', help="select core from [v2ray, xray, shadowsocks-libev]", 
                                        choices=["xray", "v2ray", "ss", "wxray"], default="xray")
    parser.add_argument("--proxychains", help="set proxychains", action="store_true")
    parser.add_argument("--system", help="set system proxy", action="store_true")
    args = parser.parse_args()

    if is_port_in_use(args.lport):
        logging.error(f"port {args.lport} is in use")
        return
    
    if args.proxychains:
        if not is_tool("proxychains"):
            logging.error("proxychains not found, please install it first")
            logging.error("\tsudo apt install proxychains")
            return
        set_proxychains(args.lport)

    logging.info(f"Starting proxy client on port {args.lport} with PID {os.getpid()}")

    if args.system:
        set_system_proxy(proxyHost="127.0.0.1", proxyPort=args.lport, enable=True)

    if args.core == "ss" and args.link.startswith("ss://"):
        if not is_tool('ss-local'):
            logging.error("ss-local not found, please install shadowsocks client first")
            logging.error("\thttps://github.com/shadowsocks/shadowsocks-libev")
            return
        ss_runner(args.link, args.lport)
    else :
        global CORE
        os.environ["PATH"] += os.pathsep + os.path.join('.', 'xray')
        os.environ["PATH"] += os.pathsep + os.path.join('.', 'v2ray')

        CORE = shutil.which(args.core)
        if not CORE :
            logging.error(f"{args.core} not found!")
            if args.core == "v2ray" :
                logging.error("you can install v2ray from https://www.v2fly.org/en_US/guide/install.html")
            else:
                logging.error("you can install xray from https://github.com/XTLS/Xray-core#installation")
            download = input("do you want to download it now? [y/n]").strip() in ["yes", "y"]
            if download :
                if args.core == "v2ray" :
                    downloadZray("v2fly", "v2ray")
                else:
                    downloadZray("XTLS", "xray")
                CORE = shutil.which(args.core)
            else:
                exit(1)

        logging.info(f"using {CORE} core")
        
        v2ray_runner(args.link, args.lport)

    if args.system:
        set_system_proxy(enable=False)


if __name__ == '__main__':
    main()
    shutil.rmtree(tempdir)

