import datetime
import glob
import os.path as path

import utils.config_parse_helper as cfg_help
import utils.errors as errs
import utils.subprocess_utils as sub_utils
from backup import Backup
from utils.config_parse_helper import ConfigSchema, ConfigSchemaSection, ConfigSchemaLine

EXPECTED_CONFIG_FILE = path.join(path.dirname(__file__), './confluence_backup.config')

CONFLUENCE_SCHEMA = ConfigSchema(
    [ ConfigSchemaSection('DEFAULT',
        [ ConfigSchemaLine('backup_paths',   True,  list,
            cfg_help.SpecialSchemaProcessing.commma_separated)
        , ConfigSchemaLine('source_machine', True,  str)
        , ConfigSchemaLine('verbose',        False, bool)
        , ConfigSchemaLine('make_dirs',      False, bool)
        ])
    , ConfigSchemaSection('COPY',
        [ ConfigSchemaLine('sources',         True,  list,
            cfg_help.SpecialSchemaProcessing.commma_separated)
        , ConfigSchemaLine('additional_args', False, list,
            cfg_help.SpecialSchemaProcessing.space_separated)
        ])
    , ConfigSchemaSection('TAR',
        [ ConfigSchemaLine('sources',         True,  list,
            cfg_help.SpecialSchemaProcessing.commma_separated)
        , ConfigSchemaLine('additional_args', False, list,
            cfg_help.SpecialSchemaProcessing.space_separated)
        , ConfigSchemaLine('target_filename', True,  str)
        , ConfigSchemaLine('prefix_date',     True,  bool)
        ])
    , ConfigSchemaSection('RSYNC',
        [ ConfigSchemaLine('sources', True, list,
            cfg_help.SpecialSchemaProcessing.commma_separated)
        , ConfigSchemaLine('additional_args', False, list,
            cfg_help.SpecialSchemaProcessing.space_separated)
        , ConfigSchemaLine('sub-dirs', False, list,
            cfg_help.SpecialSchemaProcessing.commma_separated)
        ])
    , ConfigSchemaSection('MYSQLDUMP',
        [ ConfigSchemaLine('user',            True,  str)
        , ConfigSchemaLine('password',        True,  str)
        , ConfigSchemaLine('db_name',         True,  str)
        , ConfigSchemaLine('additional_args', False, list,
            cfg_help.SpecialSchemaProcessing.space_separated)
        , ConfigSchemaLine('target_filename', True,  str)
        , ConfigSchemaLine('prefix_date',     True,  bool)
        ])
    ]
)


class ConfluenceBackup(Backup):

    def __init__(self, config_file=EXPECTED_CONFIG_FILE, schema=CONFLUENCE_SCHEMA):
        self.load_config(config_file, schema)

    @staticmethod
    def get_confluence_backup_date_format(custom_date=None):
        # Format is currently: 2019-Aug-13--0325.zip
        confluence_format = "%Y_%m_%d"
        if custom_date is not None:
            return custom_date.strftime(confluence_format)
        return datetime.date.today().strftime(confluence_format)

    def _run_copy(self, verbose=False):
        if self.should_run_copy is None or False:
            return 0

        for bp in self.default_dict['backup_paths']:
            if not path.exists(bp):
                raise errs.ValidationError(f"ValidationError: target path does not exist: {bp}")

            # For confluence backup there should only be one source:
            source = self.copy_dict['sources'][0]

            confluence_wildcard_search = f"{source}/*{ConfluenceBackup.get_confluence_backup_date_format()}*"
            confluence_xml_filepaths = glob.glob(confluence_wildcard_search)
            if len(confluence_xml_filepaths) == 0:
                raise errs.ValidationError(f"ValidationError: No confluence backups found of form: {confluence_wildcard_search}")

            for jxf in confluence_xml_filepaths:
                if not path.exists(jxf):
                    raise errs.ValidationError(f"ValidationError: target path does not exist: {jxf}")
                try:
                    args = [jxf, bp]
                    if 'additional_args' in self.copy_dict.keys():
                        args = args + self.copy_dict['additional_args']
                    sub_utils.cp_wrapper(args)
                except errs.SubprocessError as e:
                    raise errs.SubprocessError( f"Error: copying\n"
                                                f"    from: {jxf}\n"
                                                f"    to: {bp}\n"
                                              ) from e
        return 0


def main(config=EXPECTED_CONFIG_FILE, schema=CONFLUENCE_SCHEMA):
    cb = ConfluenceBackup(config, schema)
    cb.run_backup_processes()


if __name__ == "__main__":
    main()
