from ..compiler.spec_assembler import get_expanded_libs_specs
from ..compiler.compose import get_app_volume_mounts, get_lib_volume_mounts, get_testing_compose_dict
from ..systems.docker.testing_image import ensure_image_exists
from ..systems.docker import get_docker_client
from ..systems.docker.compose import write_composefile, compose_up
from ..systems.rsync import sync_repos_by_app_name, sync_repos_by_lib_name
from ..log import log_to_client

def run_app_or_lib_tests(app_or_lib_name, suite_name, test_arguments, force_recreate=False):
    docker_client = get_docker_client()
    expanded_specs = get_expanded_libs_specs()
    if app_or_lib_name in expanded_specs['apps']:
        volumes = get_app_volume_mounts(app_or_lib_name, expanded_specs)
        spec = expanded_specs['apps'][app_or_lib_name]
        sync_repos_by_app_name(expanded_specs, [app_or_lib_name])
    elif app_or_lib_name in expanded_specs['libs']:
        volumes = get_lib_volume_mounts(app_or_lib_name, expanded_specs)
        spec = expanded_specs['libs'][app_or_lib_name]
        sync_repos_by_lib_name(expanded_specs, [app_or_lib_name])
    else:
        raise RuntimeError('Argument must be defined app or lib name')

    test_command = _construct_test_command(spec, suite_name, test_arguments)
    image_name = "{}_dusty_testing/image".format(app_or_lib_name)
    ensure_image_exists(docker_client, spec['test'], image_name, volumes=volumes, force_recreate=force_recreate)
    _run_tests_with_image(expanded_specs, app_or_lib_name, spec, volumes, image_name, test_command)

def _construct_test_command(spec, suite_name, test_arguments):
    suite_command = None
    for suite_dict in spec['test']['suites']:
        if suite_dict['name'] == suite_name:
            suite_command = suite_dict['command']
            break
    if suite_command is None:
        raise RuntimeError('{} is not a valid suite name'.format(suite_name))
    test_command = '{} {}'.format(suite_command, ' '.join(test_arguments))
    log_to_client('Command to run in test is {}'.format(test_command))
    return test_command

def _services_compose_up(expanded_specs, app_or_lib_spec):
    previous_container_names = []
    for service_name in app_or_lib_spec['test']['services']:
        service_spec = expanded_specs['services'][service_name]
        kwargs = {}
        if previous_container_names:
            kwargs['net_container_identifier'] = previous_container_names[-1]
        service_compose_config = get_testing_compose_dict(service_name, service_spec, **kwargs)

        #want to make these temporary files
        compose_file = '/Users/paetling/dusty_testing/service_{}'.format(service_name)
        write_composefile(service_compose_config, compose_file)
        log_to_client('Compose config {}: \n {}'.format(service_name, service_compose_config))

        compose_up(compose_file, service_name)
        #compose only has runs with lower case names
        previous_container_names.append("{}_{}_1".format(service_name.lower(), service_name))
    return previous_container_names

def _app_or_lib_compose_up(app_or_lib_spec, app_or_lib_name, image_name,
                           app_or_lib_volumes, test_command, previous_container_name):
    kwargs = {'testing_image_identifier': image_name,
              'volumes': app_or_lib_volumes,
              'command': test_command}

    if previous_container_name is not None:
        kwargs['net_container_identifier'] = previous_container_name
    compose_file = '/Users/paetling/dusty_testing/service_{}'.format(app_or_lib_name)
    compose_config = get_testing_compose_dict(app_or_lib_name, app_or_lib_spec['test'].get('compose', {}), **kwargs)
    write_composefile(compose_config, compose_file)
    compose_up(compose_file, app_or_lib_name)
    log_to_client('Compose config {}: \n {}'.format(app_or_lib_name, compose_config))

def _run_tests_with_image(expanded_specs, app_or_lib_name, app_or_lib_spec, app_or_lib_volumes, image_name, test_command):
    log_to_client('image name is {}'.format(image_name))


    previous_container_names = _services_compose_up(expanded_specs, app_or_lib_spec)
    previous_container_name = previous_container_names[-1] if previous_container_names else None
    _app_or_lib_compose_up(app_or_lib_spec, app_or_lib_name, image_name, app_or_lib_volumes, test_command, previous_container_name)


    #need to wait on tests finishing and cleanup shit afterwards



@@ -1,24 +1,60 @@
+import os%0A%0Afrom .. import constants%0A
 from ..compiler.spec_ass
@@ -2113,16 +2113,142 @@
 ommand%0A%0A
+def _test_composefile_path(service_name):%0A    return os.path.expanduser('~/.dusty-testing/test_%7B%7D.yml'.format(service_name))%0A%0A
 def _ser
@@ -2752,65 +2752,42 @@
 pose
-_
 file
- = '/Users/paetling/dusty_testing/service_%7B%7D'.form
+_path = _test_composefile_p
 at
+h
 (ser
@@ -2850,29 +2850,33 @@
 fig, compose
-_
 file
+_path
 )%0A        lo
@@ -2987,21 +2987,25 @@
 (compose
-_
 file
+_path
 , servic
@@ -3623,65 +3623,42 @@
 pose
-_
 file
- = '/Users/paetling/dusty_testing/service_%7B%7D'.form
+_path = _test_composefile_p
 at
+h
 (app
@@ -3833,21 +3833,25 @@
  compose
-_
 file
+_path
 )%0A    co
@@ -3870,13 +3870,17 @@
 pose
-_
 file
+_path
 , ap
@@ -4162,17 +4162,16 @@
 name))%0A%0A
-%0A
     prev
@@ -4412,24 +4412,51 @@
  image_name,
+%0A                          
  app_or_lib_
@@ -4507,73 +4507,4 @@
 me)%0A
-%0A%0A    #need to wait on tests finishing and cleanup shit afterwards%0A%0A%0A

Write testing Composefile to user home for now