#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, sys

# prevent bytecode
sys.dont_write_bytecode = True

# unbuffered stdout / stderr
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)

import re, yaml
from cleo import Application

from webdevops import Configuration
from webdevops.docker.DockerBaseClient import DockerBaseClient
from webdevops.docker.DockerPyClient import DockerPyClient
from webdevops.docker.DockerCliClient import DockerCliClient
from command.docker_build_command import DockerBuildCommand
from command.docker_push_command import DockerPushCommand
from command.docker_pull_command import DockerPullCommand
from command.docker_exec_command import DockerExecCommand
from command.test_testinfra_command import TestTestinfraCommand
from command.test_serverspec_command import TestServerspecCommand
from command.generate_dockerfile_command import GenerateDockerfileCommand
from command.generate_graph_command import GenerateGraphCommand
from command.generate_provision_command import GenerateProvisionCommand

if __name__ == '__main__':
    # Generate common paths
    script_path = os.path.dirname(os.path.realpath(__file__))
    root_path = os.path.dirname(script_path)
    conf_path = os.path.join(root_path, 'conf')


    def generatePath(path):
        """
        Generate full path based on root path
        """
        return os.path.abspath(os.path.join(root_path, (path)))

    # Read console.yml for configuration
    with open(os.path.join(conf_path, 'console.yml'), 'r') as stream:
        try:
            configuration = yaml.load(stream)
            configuration['confPath'] = conf_path
        except yaml.YAMLError as e:
            configuration = None
            print ' !!! Exception while loading configuration from %s:' % conf_path
            print ''
            print e
            print ''
            sys.exit(1)

    # Check if configuration is valid
    if configuration is None:
        print ' !!! Configuration not found'
        sys.exit(1)

    # generate full paths
    path_entries = [
        'dockerPath',
        'templatePath',
        'provisionPath',
        'imagePath',
        'baselayoutPath',
        'testinfraPath',
        'serverspecPath',
        'blacklistFile',
    ]
    for key in path_entries:
        if key in configuration:
            configuration[key] = generatePath(configuration[key])

    # Translate regexp
    if 'docker' in configuration:
        if 'pathRegex' in configuration['docker']:
            configuration['docker']['pathRegex'] = re.compile(configuration['docker']['pathRegex'])

        if 'pathRegex' in configuration['docker']:
            configuration['docker']['autoPullBlacklist'] = re.compile(configuration['docker']['autoPullBlacklist'])

    if 'dockerTest' in configuration:
        if 'configuration' in configuration['dockerTest']:
            if 'imageConfigurationRegex' in configuration['dockerTest']['configuration']:
                configuration['dockerTest']['configuration']['imageConfigurationRegex'] = re.compile(configuration['dockerTest']['configuration']['imageConfigurationRegex'])

    configuration = Configuration.merge(configuration)
    configuration = Configuration.dotdictify(configuration)

    # Init application
    application = Application()
    application.add(DockerBuildCommand(configuration=configuration))
    application.add(DockerPushCommand(configuration=configuration))
    application.add(DockerPullCommand(configuration=configuration))
    application.add(DockerExecCommand(configuration=configuration))
    application.add(TestTestinfraCommand(configuration=configuration))
    application.add(TestServerspecCommand(configuration=configuration))
    application.add(GenerateDockerfileCommand(configuration=configuration))
    application.add(GenerateGraphCommand(configuration=configuration))
    application.add(GenerateProvisionCommand(configuration=configuration))

    application.run()
