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

"""Generator for Settings File.

Title: GenerateSettingsTemplate
Author: Benjamin Yvernault
contact: b.yvernault@ucl.ac.uk
Purpose: Generate your ProjectSettingsFile.py following the template described
         in this file.
"""

from __future__ import print_function

from builtins import str

import os
import re
from datetime import datetime
from dax import DAX_Settings

__author__ = 'Benjamin Yvernault'
__email__ = 'b.yvernault@ucl.ac.uk'
__purpose__ = 'Generate your ProjectSettingsFile.py following the template \
described in this file.'
__version__ = '1.0.0'
__modifications__ = '29 Septembre 2015 - Original write'

DAX_SETTINGS = DAX_Settings()
DEFAULT_EMAIL_OPTS = DAX_SETTINGS.get_email_opts()
DEFAULT_QUEUE_LIMIT = DAX_SETTINGS.get_queue_limit()

DEFAULT_TEMPLATE = '''"""Settings_{name}.

Author: {author}
contact: {email_addr}
Settings File name: {name}
Creation date: {now}
Purpose: Settings file to describe the modules/processors for the project(s)
"""

# Python packages import:
from dax import Launcher

# header:
__author__ = "{author}"
__email__ = "{email_addr}"
__purpose__ = "Settings file to describe the modules/processors for \\
the project(s)"
__settings_name__ = "{name}"
__modifications__ = "{now} - Original write"

# Arguments for Launcher:
EMAIL = "{email_addr}"
QUEUE_LIMIT = {q_limit}
PRIORITY_ORDER = {p_order}  # CHANGE THE ORDER OF PRIORITY FOR YOUR PROJECT(S)
EMAIL_OPTS = "{e_opts}"
XNAT_HOST = "{host}"

# Modules

#
# DEFINE THE MODULES YOU WANT TO RUN FOR YOUR PROJECT(S).
# E.G: VUSTP_Module_dcm2nii = Module_dcm2nii(directory="/tmp/dcm2nii_phillips")
#

# Processors

#
# DEFINE THE PROCESSORS YOU WANT TO RUN FOR YOUR PROJECT(S).
# E.G: VUSTP_1_Processor_fMRIQA = Processor_fMRIQA(mem_mb="4096", \
version="2.0.0")
#

# Associate Project with modules/processors
# modules
# ADD THE MODULES FOR EACH PROJECT OR LEAVE IT EMPTY
proj_mod = {p_mod}

# processors
# ADD THE PROCESSORS FOR EACH PROJECT OR LEAVE IT EMPTY
proj_proc = {p_proc}

# Launcher
myLauncher = Launcher(proj_proc, proj_mod, priority_project=PRIORITY_ORDER,
                      job_email=EMAIL, job_email_options=EMAIL_OPTS,
                      queue_limit=QUEUE_LIMIT, xnat_host=XNAT_HOST)
'''


def write_settings():
    """Write the ProjectSettingsFile.py from the template.

    :return: None
    """
    priority = []
    host = '%s' % ARGS.xnat_host if ARGS.xnat_host else ''
    if ARGS.p_order:
        priority = ARGS.p_order.split(",")
        p_mod = '{'
        p_proc = '{'
        for ind, project in enumerate(priority):
            if ind == 0:
                p_mod += '"%s": [],\n' % project
                p_proc += '"%s": [],\n' % project
            else:
                # 12 = length of proj_mod = {
                p_mod += '%s"%s": [],\n' % (' ' * 12, project)
                # 13 = length of proj_proc = {
                p_proc += '%s"%s": [],\n' % (' ' * 13, project)
        p_mod = p_mod[:-2] + '}'
        p_proc = p_proc[:-2] + '}'
    else:
        p_mod = '{"proj1": ["module1", "...", "moduleN"], \
"proj2": ["module1", "...", "moduleN"]}'
        p_proc = '{"proj1": ["processor1", "...", "processorN"], \
"proj2": ["processor1", "...", "processorN"]}'

    settings_code = DEFAULT_TEMPLATE.format(author=ARGS.author,
                                            email_addr=ARGS.email,
                                            name=ARGS.name,
                                            now=str(datetime.now()),
                                            q_limit=ARGS.q_limit,
                                            p_order=priority,
                                            e_opts=ARGS.e_opts,
                                            p_mod=p_mod,
                                            p_proc=p_proc,
                                            host=host)
    f_obj = open(SETTINGS_FPATH, "w")
    f_obj.writelines(settings_code)
    f_obj.close()


def parse_args():
    """Method to parse arguments base on ArgumentParser.

    :return: parser object parsed
    """
    from argparse import ArgumentParser
    argp = ArgumentParser(prog='GenerateSettingsTemplate',
                          description=__purpose__)
    argp.add_argument('-n', dest='name', required=True,
                      help='Name for ProjectSettingsFile.')
    argp.add_argument('-a', dest='author', required=True, help='Author name.')
    argp.add_argument('-e', dest='email', required=True,
                      help='Author email address.')
    argp.add_argument('-p', dest='p_order', help='Projects to process in order \
separate by a coma. E.G: ADNI,Test,Project3')
    argp.add_argument('--Qlimit', dest='q_limit', default=DEFAULT_QUEUE_LIMIT,
                      help='Queue limit on cluster to submit jobs. Default: %s'
                      % str(DEFAULT_QUEUE_LIMIT))
    argp.add_argument('--Eopts', dest='e_opts', default=DEFAULT_EMAIL_OPTS,
                      help='Options for email in the job. Default= %s'
                      % (DEFAULT_EMAIL_OPTS))
    argp.add_argument('-d', dest='directory', default=None,
                      help='Directory where the processor file will be \
generated. Default: current directory.')
    argp.add_argument('--host', dest='xnat_host', default=None,
                      help='XNAT Host to run the settings on.')
    return argp.parse_args()


if __name__ == '__main__':
    print('Deprecated executable. Use dax_generator settings instead.')
    ARGS = parse_args()

    # Get a proper name from the input
    # remove .py if present at the end of the file
    if ARGS.name.endswith('.py'):
        ARGS.name = ARGS.name[:-3]
    # remove settings if present in name
    if "settings" in ARGS.name.lower():
        settings_search = re.compile(re.escape('settings'), re.IGNORECASE)
        ARGS.name = settings_search.sub('', ARGS.name)
    # remove any particular character and change it by an underscore
    ARGS.name = re.sub('[^a-zA-Z0-9]', '_', ARGS.name)
    if ARGS.name[-1] == '_':
        ARGS.name = ARGS.name[:-1]
    # Check email:
    if ARGS.email and '@' not in ARGS.email and \
       not len(ARGS.email.split('.')) > 1:
        raise Exception("Error: email address not valid.")

    SETTINGS_NAME = """Settings_{name}.py""".format(name=ARGS.name)
    if ARGS.directory and os.path.exists(ARGS.directory):
        SETTINGS_FPATH = os.path.join(ARGS.directory, SETTINGS_NAME)
    else:
        SETTINGS_FPATH = os.path.join(os.getcwd(), SETTINGS_NAME)

    print("Generating file %s for scan processor %s ..."
          % (SETTINGS_FPATH, ARGS.name))
    write_settings()
