#!/usr/bin/env python

## see README in this directory
## depends on "txtorcon-tester" docker.io container existing
## (run "make txtorcon-testing" at top-level to achieve this)

import os
import atexit
import functools
import subprocess
import json
import time
import sys
from xml.dom import minidom

d = os.path.realpath(os.path.curdir)
container = subprocess.check_output(['docker', 'run', '-v', d+':/txtorcon:ro', '-d',
                                     'txtorcon-tester', '/txtorcon/integration/hidden_service_listen_ports/container_run'],
                                    text=True).strip()
print('container:', container)
def kill_container(container):
    print("killing", container)
    subprocess.check_output(['docker', 'kill', container])
atexit.register(functools.partial(kill_container, container))

data = subprocess.check_output(['docker', 'inspect', container])
data = json.loads(data)[0]

ip = data['NetworkSettings']['IPAddress']
print("ip address", ip)

logs_printed = 0
while True:
    logs = subprocess.check_output(['docker', 'logs', container])
    to_print = logs[logs_printed:]
    logs_printed = len(logs)
    sys.stdout.write(to_print)
    sys.stdout.flush()
    if 'liftoff' in logs:
        break
    time.sleep(1)
    continue

print("running nmap (scanning all 65535 TCP ports)...")
fname = 'txtorcon-nmap'
#print subprocess.check_output(['nmap', '-T5', '-PN', ip])
nmap = subprocess.check_output(['nmap', '-T5', '-p', '1-65535', '-oX', fname, 
                               '--open', '-sS', ip])

dom = minidom.parse(open(fname, 'r'))
ports = dom.getElementsByTagName('port')
is_error = None
if len(ports):
    print("Open ports found:")
    for e in ports:
        state = e.getElementsByTagName('state')[0].getAttribute('state')
        port = e.getAttribute('portid')
        print(port, state)
    is_error = '%d open ports found' % len(ports)

if is_error:
    print("FAILED", is_error)
    sys.exit(1)

else:
    print("OK.")
    sys.exit(0)
