#!/usr/bin/python3
# coding: utf-8
import os
import sys
import time

def utool(option):

    def print_usage():
        intro = """utool -- A self-defined command line interface, which is used to facilitate operating the system, supports the following options. In the description part, where there is a leading asterisk signifies that this option must take an argument, and for more information of this situation, simply run `utool -h` for details."""
        print(f"{c_intro}{intro}{c_e}")
        print("_" * 121)
        print(f"{c_title}|Option| Description{' ' * 40}|Option| Description{' ' * 40}|{c_e}")
        count = 0
        for opt, desc in dict_func.items():
            description = "" if desc[0] == "Reserved" else desc[0]
            if count % 2 == 0:
                print(f"{c_text}|{opt:^6}|{description:<52}{c_e}", end="")
            else:
                print(f"{c_text}|{opt:^6}|{description:<52}|{c_e}")
            count += 1
        exit(100)

    # -a
    def list_local_using_port():
        exit_on_wrong_number()
        os.system('/usr/bin/bash /opt/scripts/utool/ipports.sh port')

    # -b
    def github_two_factor():
        exit_on_wrong_number()
        os.system("/usr/bin/oathtool -b --totp 'G3NHHFO2L2LZ5W2R'")

    # -c
    def get_external_ip():
        exit_on_wrong_number()
        os.system("/usr/bin/python3 /opt/scripts/roll_api/get_self_ip.py")

    # -d
    def get_ip_location():
        exit_on_wrong_number(2)
        import re
        checked_ip = sys.argv[2]
        ipv4 = re.match(r"^((([01]?\d\d?)|(2[0-4]\d)|(25[0-5]))\.){3}(([01]?\d\d?)|(2[0-4]\d)|(25[0-5]))$", checked_ip)
        if ipv4:
            os.environ['checked_ip'] = checked_ip
            os.system('/usr/bin/python3 /opt/scripts/roll_api/get_ip.py $checked_ip')
        else:
            print(f"{c_br}Plz enter correct IP...{c_e}")
            exit(ord(option.strip('-')))

    # -e
    def gen_md5():
        if len(sys.argv) < 3:
            print(f"{c_br}需要至少一个字符串作为输入，退出...{c_e}\n")
            exit(ord(option.strip('-')))

        param=''
        for item in sys.argv[2:]:
            param += item

        os.environ['param'] = param
        print(f"{c_by}Warning: 输入字符串中间的任何空白符将会被删除，要保留的话，需手动将字符串用单引号括起来{c_e}")
        print(f"本次计算MD5值的字符串为 - {param}\n本次计算得到的MD5的值为 - ", end='')
        # print(f"本次计算得到的MD5的值为 - ", end='')
        os.system('echo -n $param | md5sum | cut -d " " -f 1')

    # -f
    def number2date():
        exit_on_wrong_number(2)
        os.environ['param'] = sys.argv[2]
        os.system('/usr/bin/bash /opt/scripts/utool/number2d.sh $param')

    # -g
    def date2number():
        if len(sys.argv) < 3:
            print(f"{c_br}-k选项：将输入的时间转换成十进制和十六进制，需要一个字符串格式的时间作为输入，退出...{c_e}\n")
            exit(ord(option.strip('-')))

        param=''
        for item in sys.argv[2:]:
            param += item + ' '

        os.environ['param'] = param
        os.system('/usr/bin/bash /opt/scripts/utool/date2n.sh $param')

    # -h
    def usage():
        exit_on_wrong_number()
        print_usage()

    # -i
    def ps_top_20():
        exit_on_wrong_number()
        os.system("/usr/bin/bash /opt/scripts/utool/ps_top_20.sh")

    # -j
    def docker_pid():
        exit_on_wrong_number(2)
        os.environ['param'] = sys.argv[2]
        os.system('/usr/bin/bash /opt/scripts/utool/pid_in_docker.sh $param')

    # -p
    def gen_passwd():
        exit_on_wrong_number(2)
        os.environ['length'] = sys.argv[2]
        os.system('/usr/bin/bash /opt/scripts/utool/genpw.sh length')

    def exit_on_wrong_number(number=1):
        if len(sys.argv) != (number+1):
            print(f"{c_br}{sys.argv[1:]}: Wrong arguments!")
            print(f"Option `{option}' will {dict_func[option][0].strip()}")
            print(f"NEED: {number}\tGIVE: {len(sys.argv)-1}\n{c_e}")
            exit(ord(option.strip('-')))

    dict_func = {
        '-a': [' print all local ports of using for now', list_local_using_port],
        '-n': ['Reserved', None],
        '-b': [' generate two-factor key of GITHUB', github_two_factor],
        '-o': ['Reserved', None],
        '-c': [' show external IP of this machine', get_external_ip],
        '-p': ['*generate password of length 1~79', gen_passwd],
        '-d': ['*show the location of ip(only v4 for now)', get_ip_location],
        '-q': ['Reserved', None],
        '-e': ['*generate md5 value of the input string', gen_md5],
        '-r': ['Reserved', None],
        '-f': ['*convert a (hexa)decimal to specific time format', number2date],
        '-s': ['Reserved', None],
        '-g': ['*convert multi-formats time to a decimal', date2number],
        '-t': ['Reserved', None],
        '-h': [' show this help information and exit', print_usage],
        '-u': ['Reserved', None],
        '-i': [' print top 20 mem and cpu process', ps_top_20],
        '-v': ['Reserved', None],
        '-j': ['*find a docker subprocess, if true then print info', docker_pid],
        '-w': ['Reserved', None],
        '-k': ['Reserved', None],
        '-x': ['Reserved', None],
        '-l': ['Reserved', None],
        '-y': ['Reserved', None],
        '-m': ['Reserved', None],
        '-z': ['Reserved', None],
    }
    return dict_func[option][1]



def main():
    global option
    options = [ '-' + chr(x) for x in range(ord('a'), ord('z')+1)]
    print_usage = utool('-h')

    if len(sys.argv) > 1:
        option = sys.argv[1]
        if option in options:
            func = utool(option)
            if func == None:
                print(f"{c_bg}Option `{option}' is reserved for now...{c_e}\n")
            else:
                func()
        else:
            print_usage()
    else:
        print_usage()

# global area below ↓
c_title = '\033[1;4;37;40m'     # title color
c_text = '\033[37;40m'          # text color
c_intro = '\033[3;32m'          # text color
c_br = '\033[1;31m'             # bold red
c_bg = '\033[1;32m'             # bold green
c_by = '\033[1;33m'             # bold yellow
c_bb = '\033[1;34m'             # bold blue
c_bp = '\033[1;35m'             # bold purple
c_bc = '\033[1;36m'             # bold cyan
c_bir= '\033[1;3;31m'           # * bold italic red
c_bib = '\033[1;3;34m'          # * bold italic cyan
c_bic = '\033[1;3;36m'          # bold italic cyan
c_e = '\033[0m'                 # reset

if __name__ == '__main__':
    main()


