#!/usr/bin/env python

"""
Main script for starting LocalStack components.

Usage:
  localstack start [ --docker ]
  localstack web [ --port=<port> ]
  localstack (-v | --version)
  localstack (-h | --help)

Options:
  -h --help         Show this screen
  -v --version      Show version
  --docker          Run the infrastructure in a Docker container
  --port=<port>     Network port for running the Web server
"""

import os
import sys
import time
import subprocess

PARENT_FOLDER = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
if os.path.isdir(os.path.join(PARENT_FOLDER, '.venv')):
    sys.path.insert(0, PARENT_FOLDER)

from docopt import docopt
from localstack import config, constants
from localstack.services import infra
from localstack.constants import DEFAULT_PORT_WEB_UI
from localstack.utils.common import run, ShellCommandThread

if __name__ == "__main__":
    args = docopt(__doc__)

    if args['--version']:
        print(constants.VERSION)
    elif args['start']:
        print('Starting local dev environment. CTRL-C to quit.')
        if args['--docker']:
            services = os.environ.get('SERVICES', '')
            entrypoint = os.environ.get('ENTRYPOINT', '')
            cmd = os.environ.get('CMD', '')
            image_name = os.environ.get('IMAGE_NAME', constants.DOCKER_IMAGE_NAME)
            service_ports = config.SERVICE_PORTS
            max_port = max(4592, max(service_ports.values()))
            port_mappings = '-p {min_port}-{max_port}:{min_port}-{max_port}'.format(
                min_port=min(service_ports.values()), max_port=max_port)

            if services:
                port_mappings = ''
                for service, port in service_ports.items():
                    port_mappings += ' -p {port}:{port}'.format(port=port)

            env_str = ''
            for env_var in config.CONFIG_ENV_VARS:
                value = os.environ.get(env_var, None)
                if value is not None:
                    env_str += '-e %s="%s" ' % (env_var, value)

            data_dir_mount = ''
            data_dir = os.environ.get('DATA_DIR', None)
            if data_dir is not None:
                container_data_dir = '/tmp/localstack_data'
                data_dir_mount = '-v "%s:%s" ' % (data_dir, container_data_dir)
                env_str += '-e DATA_DIR="%s" ' % container_data_dir

            docker_cmd = ('docker run -it %s %s' +
                '-p 8080:8080 %s %s' +
                '-v "%s:/tmp/localstack" -v "%s:%s" ' +
                '-e DOCKER_HOST="unix://%s" ' +
                '-e HOST_TMP_FOLDER="%s" "%s" %s') % (
                    entrypoint, env_str, port_mappings, data_dir_mount, config.TMP_FOLDER,
                    config.DOCKER_SOCK, config.DOCKER_SOCK, config.DOCKER_SOCK,
                    config.HOST_TMP_FOLDER, image_name, cmd
                )

            run('mkdir -p "{folder}"; chmod -R 777 "{folder}";'.format(folder=config.TMP_FOLDER))
            print(docker_cmd)
            t = ShellCommandThread(docker_cmd, outfile=subprocess.PIPE)
            t.start()
            time.sleep(2)
            t.process.wait()
        else:
            infra.start_infra()
    elif args['web']:
        import localstack.dashboard.api
        port = args['--port'] or DEFAULT_PORT_WEB_UI
        localstack.dashboard.api.serve(port)
