"""Module containing the logic for auto generate batch script"""

import re
from datetime import datetime

from dgspoc.utils import File
from dgspoc.utils import DotObject

from dgspoc.constant import FWTYPE


class BatchBuilder:
    def __init__(self, options):
        self.options = options

        self.lookup_fmt = '# %s script is generated by Describe-Get-System'
        self.lookup_pattern = ('# (?P<framework>unitest|pytest|robotframework) '
                               'script is generated by Describe-Get-System')

        self.tbl = DotObject(unittest=[], pytest=[], robotframework=[])

        self.unittest_execution_cmdline = ''
        self.pytest_execution_cmdline = ''
        self.robotframework_execution_cmdline = ''

    @property
    def script(self):
        self.prepare_console_cmdline()

        tbl = DotObject(unittest=[], pytest=[], robotframework=[])
        operands = self.options.operands[1:]
        if not len(operands):
            for case in tbl:
                self.prepare_files('.', case=case, table=tbl)
        else:
            for item in operands:
                item = item.strip()
                if item.lower() in tbl:
                    case = item.lower()
                    self.prepare_files('.', case=case, table=tbl)
                else:
                    pat = (r'(?i)(?P<case>unittest|pytest|robotframework) '
                           r'*= *(?P<directory>\S+.*) *$')
                    match = re.match(pat, item)
                    if match:
                        directory = match.group('directory').strip()
                        case = match.group('case').lower().strip()
                        self.prepare_files(directory, case=case, table=tbl)
                    else:
                        directory = item
                        if File.is_dir(directory):
                            for case in tbl:
                                self.prepare_files(directory, table=tbl, case=case)
                        else:
                            self.prepare_files(directory, table=tbl)

        lst = []
        for fw, files in tbl.items():
            if files:
                if fw == FWTYPE.UNITTEST and self.unittest_execution_cmdline not in lst:
                    lst.append(self.unittest_execution_cmdline)
                elif fw == FWTYPE.PYTEST and self.pytest_execution_cmdline not in lst:
                    lst.append(self.pytest_execution_cmdline)
                else:
                    if self.robotframework_execution_cmdline not in lst:
                        lst.append(self.robotframework_execution_cmdline)

        batch_script = '\n'.join(lst)
        return batch_script

    def prepare_console_cmdline(self):
        dt = datetime.now()
        kwargs = DotObject(prefix='', extension='xml', ref_datetime=dt)
        method = File.get_filepath_timestamp_format1

        # unittest execution
        kwargs.prefix = 'unittest_report'
        fn = method(**kwargs)
        unittest_fmt = 'python -m xmlrunner discover dgs_test_script_files/unittest --output-file=%s'
        self.unittest_execution_cmdline = unittest_fmt % fn

        # pytest execution cmdline
        kwargs.prefix = 'pytest_report'
        fn = method(**kwargs)
        pyttest_fmt = 'python -m pytest --junitxml=%s dgs_test_script_files/pytest'
        self.pytest_execution_cmdline = pyttest_fmt % fn

        # robotframework execution cmdline
        kwargs.prefix = 'robotframework_output'
        output_fn = method(**kwargs)
        kwargs.prefix = 'robotframework_log'
        kwargs.extension = 'html'
        log_fn = method(**kwargs)
        kwargs.prefix = 'robotframework_report'
        report_fn = method(**kwargs)
        robot_fmt = ('python -m robot --output=%s --log=%s --report=%s '
                     'dgs_test_script_files/robotframework')
        self.robotframework_execution_cmdline = robot_fmt % (output_fn, log_fn, report_fn)

    def get_test_script_files(self, directory, case=''):
        filenames = File.get_list_of_filenames(top=directory, pattern='[.](py|robot)$')
        if not filenames:
            result = DotObject(files=[], message=File.message, total=0, case=case)
            return result

        lookup = self.lookup_fmt % case if case else self.lookup_pattern

        lst = []
        for filename in filenames:
            if case:
                chk = File.quicklook(filename, lookup=lookup)
                if chk:
                    lst.append(filename)
            else:
                content = File.get_content(filename)
                match = re.search(lookup, content)
                if match:
                    case = match.group('framework')
                    lst.append(filename)

        result = DotObject(files=lst, message='', total=len(lst), case=case)
        return result

    def prepare_files(self, directory, case='', table=None):
        result = self.get_test_script_files(directory, case=case)
        if result.files:
            case = case or result.case
            dst_dir = 'dgs_test_script_files/%s' % case
            copied_files = File.copy_files(result.files, dst_dir)
            table[case] = list(set(table[case] + copied_files))
