#!/usr/bin/env python3
# ./dev --help

import argparse
from http.client import HTTPException
import os
from subprocess import call
import sys
from threading import Thread
import time
from urllib.error import URLError
from urllib.request import urlopen
import webbrowser

parser = argparse.ArgumentParser(prog='./dev')
subparsers = parser.add_subparsers(metavar='<command>', title='commands')

def open_in_browser():
    site = 'http://localhost:8080'
    while True:
        try:
            urlopen(site)
            webbrowser.open(site)
            return
        except (ConnectionError, URLError, HTTPException):
            time.sleep(1)

def run(port=False):
    command = ['docker', 'run', '--init', '-it', '--rm', '-v',
              os.getcwd() + ':/src:cached', '-w=/src']
    if port:
        command += ['-p', '127.0.0.1:8080:8080']

    command.append('node:18.16.0-alpine')

    return command

def format(args, remaining):
    call(run() + ['yarn', 'format'])
parser_format = subparsers.add_parser('format',
    help='format the code')
parser_format.set_defaults(func=format)

def lint(args, remaining):
    call(run() + ['yarn', 'lint'])
parser_lint = subparsers.add_parser('lint',
    help='lint the code')
parser_lint.set_defaults(func=lint)

def start(args, remaining):
    Thread(target=open_in_browser).start()
    call(run(True) + ['yarn', 'start'])
parser_start = subparsers.add_parser('start',
    help='start a development environment')
parser_start.set_defaults(func=start)

def sh(args, remaining):
    call(run() + ['sh'])
parser_sh = subparsers.add_parser('sh', help='bring up a shell')
parser_sh.set_defaults(func=sh)

def yarn(args, remaining):
    call(run() + ['yarn'] + remaining or [])
parser_yarn = subparsers.add_parser('yarn', help='run a yarn command')
parser_yarn.set_defaults(func=yarn)

if len(sys.argv) > 1:
    args, remaining = parser.parse_known_args()
    args.func(args, remaining)
else:
    parser.print_help()
