#!/usr/bin/env python3

import sys
import os
import logging
import json
import getopt
import bottle

import ccbrowse


def usage():
    sys.stderr.write('''Usage: {program_name} [OPTIONS] [[HOST:]PORT]
       {program_name} --help
Try `{program_name} --help' for more information.
'''.format(program_name=program_name))


def print_help():
    sys.stderr.write('''Usage: {program_name} [OPTIONS] [[HOST:]PORT]
       {program_name} --help

Run the ccbrowse HTTP server.

Positional arguments:
  HOST              hostname (default: localhost)
  PORT              port (default: 8080)

Optional arguments:
  -c FILE           configuration file (default: config.json)
  -d                print debugging information
  --help            print this help information and exit
  -s SERVER         server backend or "help" to print a list of backends
  -w WORKERS        number of server backend workers

Report bugs to <ccplot-general@lists.sourceforge.net>.
'''.format(program_name=program_name))


def print_server_backends():
    print('\n'.join(bottle.server_names))


if __name__ == '__main__':
    program_name = 'ccbrowse server'
    logging.basicConfig(format=program_name+': %(message)s', level=logging.INFO)
    os.setpgrp()

    config = ccbrowse.config.default_config
    filename = 'config.json'
    server = None
    workers = None
    debug = False

    # Command line arguments.
    try: opts, args = getopt.getopt(sys.argv[1:], 'c:ds:w:', ['help'])
    except getopt.GetoptError as e:
        logging.error(e)
        usage()
        sys.exit(1)

    for opt,value in opts:
        if opt == '-d':
            debug = True
        elif opt == '-c':
            filename = value
        elif opt == '-s':
            if value == 'help':
                print_server_backends()
                sys.exit(0)
            if value not in bottle.server_names:
                logging.error('Invalid server backend "%s"' % value)
                sys.exit(1)
            server = value
        elif opt == '-w':
            try:
                workers = int(value)
                assert(workers > 0)
            except (ValueError, AssertionError):
                logging.error('Invalid number of workers "%s"' % value)
                sys.exit(1)
            workers = value
        elif opt == '--help':
            print_help()
            sys.exit(0)

    if len(args) > 1:
        usage()
        sys.exit(1)

    try:
        with open(filename) as fp:
            config.update(json.load(fp))
    except ValueError as e:
        logging.error('%s: %s' % (filename, e))
        sys.exit(1)
    except IOError as e:
        logging.error('%s: %s' % (e.filename, e.strerror))
        sys.exit(1)

    config['debug'] = debug

    host = None
    port = None
    if len(args) == 1:
        i = args[0].rfind(':')
        if i == -1: port = args[0]
        else:
            host = args[0][:i]
            port = args[0][(i+1):]

    if server != None: config['server'] = server
    if workers != None: config['workers'] = workers
    if host != None: config['host'] = host
    try:
        if port != None: config['port'] = int(port)
    except ValueError:
        logging.error('Invalid port number %s' % args[0][i+1:])
        sys.exit(1)
    try: ccbrowse.server.run(config)
    except RuntimeError as e:
        logging.error(e)
        sys.exit(1)
    except KeyboardInterrupt: pass
