import os
import sys

from py_autoflow.cli_manager import *
from py_autoflow.logging import parse_log

ROOT_PATH=os.path.dirname(__file__)
TEMPLATES_PATH = os.path.join(ROOT_PATH, 'templates')
IGNORE_FILES = ['execution.sh', 'wf.json', 'output']

def test_basic_template(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, 'basic.af', 'exec', 'basic.json', ignore_files = IGNORE_FILES)

def test_simple_iter1to1_template(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, 'simple_iter1to1.af', 'simple_iter1to1', 'simple_iter1to1.json', ignore_files = IGNORE_FILES)

def test_simple_ManyTo1_template(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, 'simple_ManyTo1.af', 'simple_ManyTo1', 'simple_ManyTo1.json', ignore_files = IGNORE_FILES)

def test_2depsTo1task_template(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, '2depsTo1task.af', '2depsTo1task', '2depsTo1task.json', ignore_files = IGNORE_FILES)

def test_regexp_deps_ManyTo1_template(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, 'regexp_deps_ManyTo1.af', 'regexp_deps_ManyTo1', 'regexp_deps_ManyTo1.json', ignore_files = IGNORE_FILES)

def test_regexp_deps_ManyTo1withOr_template(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, 'regexp_deps_ManyTo1withOr.af', 'regexp_deps_ManyTo1withOr', 'regexp_deps_ManyTo1withOr.json', ignore_files = IGNORE_FILES)

def test_regexp_iterative_tasks_template(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, 'regexp_iterative_tasks.af', 'regexp_iterative_tasks', 'regexp_iterative_tasks.json', ignore_files = IGNORE_FILES)

def test_linked_folders(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, 'basic.af', 'linked_folders', 'basic.json', extra_af_args='-L', ignore_files = IGNORE_FILES)

def test_white_list_template(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, 'basic.af', 'white_list', 'basic_white.json', extra_af_args='--white_list alg*', ignore_files = IGNORE_FILES)

def test_white_list_2task_template(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, 'basic3.af', 'white_list2task', 'basic_white2task.json', extra_af_args='--white_list alg*,result', ignore_files = IGNORE_FILES)

def test_black_list_template(tmp_dir, compare_workflow):
	compare_workflow(tmp_dir, 'basic.af', 'black_list', 'basic_black.json', extra_af_args='--black_list alg*', ignore_files = IGNORE_FILES)

def test_var_parsing_template(tmp_dir, compare_workflow):
	vars_file = os.path.join(TEMPLATES_PATH, 'basic_with_vars.var')
	compare_workflow(tmp_dir, 'basic_with_vars.af', 'var_parsing', 'basic_with_vars.json', extra_af_args=f"-V $file_name=test,{vars_file}", ignore_files = IGNORE_FILES)
	#compare_workflow(tmp_dir, 'basic_with_vars.af', 'var_parsing', 'basic_with_vars.json', extra_af_args=f"-V file_name=test,file_folder=exec", ignore_files = IGNORE_FILES)

def test_basic_stack_inspect(tmp_dir):
	args = f"-v -w {os.path.join(TEMPLATES_PATH, 'basic.af')} -o {os.path.join(tmp_dir, 'stack_inspect')}".split(" ")
	autoflow(args)
	assert True == True

def test_basic_logging(tmp_dir):
	args = f"-b -w {os.path.join(TEMPLATES_PATH, 'basic.af')} -o {os.path.join(tmp_dir, 'wf_logging')}".split(" ")
	autoflow(args)
	log_path = os.path.join(tmp_dir, 'wf_logging', '.wf_log')
	args =f"-e {os.path.join(log_path, 'echo_0000')} -s algo".split(" ")
	flow_logger(args)
	args =f"-e {os.path.join(log_path, 'echo_0000')} -f algo".split(" ")
	flow_logger(args)
	log = parse_log(log_path, fill_attribs = False)
	log_simplified = {}
	for k, val in log.items(): log_simplified[k] = list(val.keys())
	assert log_simplified == {'result': ['set'], 'algo': ['set', 'start', 'end']}

def test_basic_reporting(tmp_dir):
	args = f"-b -w {os.path.join(TEMPLATES_PATH, 'basic.af')} -o {os.path.join(tmp_dir, 'wf_reporting')}".split(" ")
	autoflow(args)
	log_path = os.path.join(tmp_dir, 'wf_reporting', '.wf_log')
	args =f"-e {os.path.join(log_path, 'echo_0000')} -s algo".split(" ")
	flow_logger(args)
	args =f"-e {os.path.join(log_path, 'echo_0000')} -f algo".split(" ")
	flow_logger(args)
	args =f"-e {os.path.join(log_path, 'touch_0000')} -s result".split(" ")
	flow_logger(args)
	args =f"-e {os.path.join(log_path, 'touch_0000')} -f result".split(" ")
	flow_logger(args)
	args =f"-e {os.path.join(tmp_dir, 'wf_reporting')} -w -r ALL".split(" ")
	report = flow_logger(args)
	assert report.export_text() == '                    Logging                     \n┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━┳━━━━━━━━━━┓\n┃ Status ┃ Folder     ┃ Time ┃ Size ┃ Job Name ┃\n┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━╇━━━━━━━━━━┩\n│ SUCC   │ touch_0000 │ -    │ 8,0K │ result   │\n│ SUCC   │ echo_0000  │ -    │ 12K  │ algo     │\n└────────┴────────────┴──────┴──────┴──────────┘\n'

def test_basic_reporting_no_finished(tmp_dir):
	args = f"-b -w {os.path.join(TEMPLATES_PATH, 'basic.af')} -o {os.path.join(tmp_dir, 'wf_reporting_nof')}".split(" ")
	autoflow(args)
	log_path = os.path.join(tmp_dir, 'wf_reporting_nof', '.wf_log')
	args =f"-e {os.path.join(log_path, 'echo_0000')} -s algo".split(" ")
	flow_logger(args)
	args =f"-e {os.path.join(log_path, 'echo_0000')} -f algo".split(" ")
	flow_logger(args)
	args =f"-e {os.path.join(log_path, 'touch_0000')} -s result".split(" ")
	flow_logger(args)
	args =f"-e {os.path.join(tmp_dir, 'wf_reporting_nof')} -r ALL".split(" ")
	report = flow_logger(args)
	assert report.export_text() == '                    Logging                     \n┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━┳━━━━━━━━━━┓\n┃ Status ┃ Folder     ┃ Time ┃ Size ┃ Job Name ┃\n┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━╇━━━━━━━━━━┩\n│ RUN    │ touch_0000 │ -    │ 8,0K │ result   │\n│ SUCC   │ echo_0000  │ -    │ 12K  │ algo     │\n└────────┴────────────┴──────┴──────┴──────────┘\n'

def test_failed_jobs_launching(tmp_dir):
	args = f"-b -w {os.path.join(TEMPLATES_PATH, 'basic_failed.af')} -o {os.path.join(tmp_dir, 'failed_launching')}".split(" ")
	autoflow(args)
	log_path = os.path.join(tmp_dir, 'failed_launching', '.wf_log')
	args =f"-e {os.path.join(log_path, 'echo_0000')} -s algo".split(" ")
	flow_logger(args)
	args =f"-e {os.path.join(log_path, 'echo_0000')} -s other".split(" ") # we add a task that is fully completed to check that is not listed for flow_logger to launch
	flow_logger(args)
	args =f"-e {os.path.join(log_path, 'echo_0000')} -f other".split(" ")
	flow_logger(args)
	args =f"-b -e {os.path.join(tmp_dir, 'failed_launching')} -l -w".split(" ")
	out = flow_logger(args)
	results = {}
	for name, job in out.items():
		results[name] = job.attrib['done']
	assert results == {'algo': False, 'result': False}

