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

import os, sys
import argparse
from collections import defaultdict

from luiti import luigi, manager
lc = luigi.luiti_config
curr_dir  = os.getcwd()

def bool_type(arg1):
    arg2 = arg1.lower()
    if arg2 == 'false': return False
    if arg2 == 'true':  return True
    raise ValueError("[err value] %s" % arg1)


# 1. parser
parser_main    = argparse.ArgumentParser(description="Luiti tasks manager.")
subparsers     = parser_main.add_subparsers(title="subcommands", description='valid subcommands',)

parser_ls   = subparsers.add_parser('ls', help=u"list all current luiti tasks.")

parser_new  = subparsers.add_parser('new', help=u"create a new luiti project.")
# TODO remove argument key, just value only.
parser_new.add_argument('--project-name',       help=u"必须指定项目名称，比如 --project-name=table_base", required=True, )

parser_gene = subparsers.add_parser('generate', help=u"generate a new luiti task python file.")

parser_info = subparsers.add_parser('info', help=u"show a detailed task.")

parser_clean   = subparsers.add_parser('clean', help=u"manage files that outputed by luiti tasks.")
parser_run = subparsers.add_parser('run', help=u"run a luiti task.")

for parser_1 in [parser_ls, parser_gene, parser_info, parser_clean, parser_run]:
    parser_1.add_argument("--project-dir", help=u"force use another project directory.", default=curr_dir)

    if parser_1 not in [parser_ls, parser_new]:
        parser_1.add_argument('--task-name', help=u"必须指定任务名称，比如 --task-name=Redmine5954ParentReportWeek",   required=True, )

parser_clean.add_argument('--date-range',        help=u"必须指定时间周期，比如 --date-range=20141001-20141015",            required=True, )
parser_clean.add_argument('--dry',               help=u"可以指定 **假运行** 模式 , 比如 --dry=true。",                     default=True,  choices=[True, False], type=bool_type)
parser_clean.add_argument('--dep',               help=u"可以指定 --dep=true，这样就会寻找依赖于当前Task之上的任务",        default=False, choices=[True, False], type=bool_type)
parser_clean.add_argument('--force',             help=u"强制删除文件",                                                     default=False, choices=[True, False], type=bool_type)

parser_run.add_argument('--date-value',          help=u"必须指定具体时间，比如 --date-value=2014-09-01T00:00:01+08:00 。后面的时区信息是必须的。",   required=True, )


# check arguments
if len(sys.argv) == 1:
    parser_main.print_help()
    exit(0)
else:
    args_main  = parser_main.parse_args()
    subcommand = sys.argv[1]

    if "project_dir" in args_main:
        lc.curr_project_dir = args_main.project_dir


# check valid project.
if subcommand != "new": # not new a project
    if not os.path.exists(os.path.join(lc.curr_project_dir, "luiti_tasks")):
        print u"""
    Current work directory '%s' has no sub directory 'luiti_tasks', make sure you have already `cd path/to/your/luiti/project/` .
        """ % (lc.curr_project_dir)
        exit(1)

if ("task_name" in args_main) and (subcommand not in ["generate"]):
    curr_task = manager.load_a_task_by_name(args_main.task_name)


if subcommand == "ls": manager.print_all_tasks(manager.ld.result)

if subcommand == "new": manager.new_a_project(args_main.project_name)
if subcommand == "generate": manager.generate_a_task(args_main.task_name)

if subcommand == "info":
    dep_tasks_on_curr_task = manager.find_dep_on_tasks(curr_task, manager.ld.all_task_classes)
    manager.Table.print_task_info(curr_task, dep_tasks_on_curr_task)

if subcommand == "clean":
    dep_tasks_on_curr_task = [curr_task]
    if args_main.dep:
        dep_tasks_on_curr_task = manager.find_dep_on_tasks(curr_task, manager.ld.all_task_classes)
        dep_tasks_on_curr_task.insert(0, curr_task)
    dep_file_to_task_instances = manager.get_all_date_file_to_task_instances(args_main.date_range, dep_tasks_on_curr_task)

    manager.print_files_by_task_cls_and_date_range(
                            curr_task,
                            args_main,
                            {
                                "dep_file_to_task_instances" : dep_file_to_task_instances,
                                "task_classes_count"         : len(dep_tasks_on_curr_task),
                                "dep_tasks_on_curr_task"     : dep_tasks_on_curr_task,
                            })

    if args_main.dry:
        print "\nTips: just set --dry=false to soft-delete theses files.\n"
    else:
        manager.soft_delete_files(*dep_file_to_task_instances.keys())

if subcommand == "run":
    # 1. 把参数修复为 luigi 接受的参数，即把只有 luiti 依赖的参数去除。
    manager.SysArgv.convert_to_luigi_accepted_argv(subparsers)

    # 2. run it!
    luigi.run(main_task_cls=curr_task)
