import configparser
import os
from pathlib import Path

import mailman_backup as mailbck_mod
import backup as bckup
from backup import DEFAULT_SCHEMA_SECTION, RSYNC_SCHEMA_SECTION
from mailman_backup import MailmanBackup
from utils.config_parse_helper import ConfigSchema


MAILMAN_TEST_CONFIG = os.path.join(os.path.dirname(__file__),
    './testing/mailman_test.config')


class TestArguments(object):

    def assert_defaults(self, mb: MailmanBackup):

        assert mb.default_dict == \
            { 'backup_paths' :  [ '/export/ippops3.0/backups/mailman_backups'
                                , '/data/ippops4.0/backups/mailman_backups'
                                , '/data/ippops5.0/backups/mailman_backups'
                                ]
            , 'source_machine' : 'ippops3'
            , 'verbose' : False
            }
        assert mb.rsync_dict == \
            { 'sources' : ['/var/lib/mailman']
            , 'additional_args' : ['-a', '--delete-after', '--copy-links']
            }

    def test_load_default_config_file(self):
        mb = MailmanBackup(config_file=MAILMAN_TEST_CONFIG)
        self.assert_defaults(mb)


class TestFullRunFromMain(object):

    def test_main_loads_and_runs_fine_when_given_config(self, tmpdir):
        config = configparser.ConfigParser()
        bpath1 = os.path.join(tmpdir, "path/1")
        bpath2 = os.path.join(tmpdir, "path/2")
        config['DEFAULT'] = \
            { 'backup_paths' :  f"{bpath1}, {bpath2}"
            , 'source_machine' : 'rocket'
            , 'verbose' : 'True'
            }
        tar_source =  os.path.join(tmpdir, "tar/source")
        config['TAR'] = \
            { 'sources' : f"{tar_source}"
            , 'additional_args' : "--verbose -z -p -cf"
            , 'target_filename' : 'svnroot.tar.gz'
            , 'prefix_date' : 'False'
            }
        os.makedirs(bpath1)
        os.makedirs(bpath2)
        os.makedirs(tar_source)

        schema = ConfigSchema(None)
        schema.add_section(bckup.DEFAULT_SCHEMA_SECTION)
        schema.add_section(bckup.TAR_SCHEMA_SECTION)

        mailbck_mod.main(config, schema)
        assert True is True


class TestMailmanRsync(object):
    """Simple inherit of base class Backup"""

    def test_rsync_with_additional_args(self, tmpdir):

        # Setup config
        backup_1_path = os.path.join(tmpdir, "backup_1_path")
        backup_2_path = os.path.join(tmpdir, "backup_2_path")
        config = configparser.ConfigParser()
        config['DEFAULT'] = \
            { 'backup_paths' :  f"{backup_1_path}, {backup_2_path}"
            , 'source_machine' : 'ippops3'
            , 'verbose' : 'True'
            }
        config['RSYNC'] = \
            { 'sources' : f"{os.path.join(tmpdir, 'mailman')}"
            , 'additional_args' : "-a --delete-after"
            }
        backup_1_path = os.path.join(tmpdir, "backup_1_path")
        backup_2_path = os.path.join(tmpdir, "backup_2_path")
        os.makedirs(backup_1_path)
        os.makedirs(backup_2_path)

        # Create files to be Rync'd
        mailman_root = os.path.join(tmpdir, "mailman")
        subdir = os.path.join(mailman_root, "some_dir")
        file = os.path.join(subdir, "file_in_subdir")
        os.makedirs(mailman_root)
        os.makedirs(subdir)
        Path(file).touch()

        # Setup Schema
        schema = ConfigSchema(None)
        schema.add_section(DEFAULT_SCHEMA_SECTION)
        schema.add_section(RSYNC_SCHEMA_SECTION)

        # check that the rsync is successful (with options)
        mb = MailmanBackup(config, schema)

        expected1dir  = os.path.join(tmpdir, 'backup_1_path', 'mailman', 'some_dir')
        expected1file = os.path.join(tmpdir, 'backup_1_path', 'mailman', 'some_dir/file_in_subdir')
        expected2dir  = os.path.join(tmpdir, 'backup_2_path', 'mailman', 'some_dir')
        expected2file = os.path.join(tmpdir, 'backup_2_path', 'mailman', 'some_dir/file_in_subdir')
        assert not os.path.exists(expected1dir)
        assert not os.path.exists(expected1file)
        assert not os.path.exists(expected2dir)
        assert not os.path.exists(expected2file)
        mb._run_rsync()
        assert os.path.exists(expected1dir)
        assert os.path.exists(expected1file)
        assert os.path.exists(expected2dir)
        assert os.path.exists(expected2file)
