#!/usr/bin/env python3
from subprocess import Popen, PIPE
from getopt import gnu_getopt, GetoptError
from json import dumps, loads
from os import environ

from sys import stdout, stdin

if environ.get('SLOW_MEMORY') == None:
    environ['SLOW_MEMORY'] = 'warn'
if environ.get('WORK_GROUP') == None:
    environ['WORK_GROUP'] = 'testing'

xmr = {
    'config.txt': {
        "call_timeout": 10,
        "retry_time": 30,
        "giveup_limit": 0,
        "verbose_level": 4,
        "print_motd": False,
        "h_print_time": 300,
        "aes_override": None,
        "use_slow_memory": environ['SLOW_MEMORY'],
        "tls_secure_algo": True,
        "daemon_mode": False,
        "output_file": "", #"/var/log/xmr-stak-rx.log",
        "httpd_port": 8080,
        "http_login": "",
        "http_pass": "",
        "prefer_ipv4": False,
    },
    'pools.txt': { "pool_list": [ {
        "pool_address":  "europe.randomx-hub.miningpoolhub.com:20580",
        "wallet_address":  f"Ghost-Zephyr.{environ['WORK_GROUP']}", "rig_id" : "",
        "pool_password": "x", "use_nicehash": False, "use_tls": False, "tls_fingerprint": "",
        "pool_weight": 1 },
    ], "currency": "monero" },
    'cpu.txt': {
        "cpu_threads_conf" : [
            #{ "low_power_mode": 5, "affine_to_cpu": false },
        ]
    }
}

sys = []

def usage():
    print('''
Docker cryptominer script.
Automagically generates configs and runs miner programs inside a container.

    -h --help, shows this.
    -m --monero [n], mines monero with n threads.
''')

def main(argv):
    try:
        opts, _ = gnu_getopt(argv, 'm:h', ['monero=', 'help'])
        if len(opts) < 1:
            usage()
            exit()
        for o, a in opts:
            if o in ('-m', '--monero'):
                monero(a)
            elif o in ('-h', '--help'):
                usage()
                exit()
            else:
                assert False, "unhandled option"
        #calls(sys)
    except GetoptError as err:
        print(f'\n{err}')
        usage()

def  monero(threads):
    try:
        for _ in range(0, int(threads)):
            xmr['cpu.txt']['cpu_threads_conf'].append({ "low_power_mode": 5, "affine_to_cpu": False })
        for c in xmr:
            with open(c, 'r') as f:
                d = f.readline()
            if f'{dumps(xmr[c])[1:-1]},' != d:
                with open(c, 'w') as f:
                    f.write(f'{dumps(xmr[c])[1:-1]},')
                print(f'Config {c} updated.')
            else:
                print(f'Config {c} unchanged.')
        #sys.append(xmr)
        p = Popen(['./xmr-stak-rx', '--currency', 'monero', '--config', 'config.txt', '--noDevSupport', '--noTest'], stdout=PIPE, stderr=PIPE, stdin=stdin)
        for c in iter(lambda: p.stdout.readline(1), b''): stdout.write(c.decode('utf-8'))
    except KeyboardInterrupt:
        p.terminate()
        o, _ = p.communicate()
        print(o.decode('utf-8'))
    except NameError:
        print('\\nGot keyboard interrupt beafore starting xmr-stak-rx.')
    except ValueError:
        print('\nThreads has to be a number.')
        usage()

def calls(sys):
    if len(sys) > 1:
        raise NotImplementedError # TODO: syscall hander with std pipes to run multiple miners at once. subprocess.Popen?
    if 'xmr' in sys:
        p = Popen('./xmr-stak-rx --currency monero --config config.txt --noDevSupport --noTest', shell=True, stdout=PIPE, stderr=PIPE, stdin=stdin)
        o, _ = p.communicate()
        print(o.decode('utf-8'))

if __name__ == '__main__':
    from sys import argv
    main(argv[1:])

