import configparser
import os
from pathlib import Path

import backup as bckup
import website_backup as webbck_mod
from website_backup import WebsiteBackup
from utils.config_parse_helper import ConfigSchema

WEBSITE_TEST_CONFIG = os.path.join(os.path.dirname(__file__),
    './testing/website_test.config')


class TestArguments(object):

    def assert_defaults(self, wb: WebsiteBackup):

        assert wb.default_dict == \
            { 'backup_paths' :  [ '/export/ippops3.0/backups/website_backups'
                                , '/data/ippops4.0/backups/website_backups'
                                , '/data/ippops5.0/backups/website_backups'
                                ]
            , 'source_machine' : 'ippops3'
            , 'verbose' : False
            }
        assert wb.rsync_dict == \
            { 'sources' : ['/export/ippc20.0/www']
            , 'additional_args' : ['-a', '--delete-after']
            }

    def test_load_default_config_file(self):
        wb = WebsiteBackup(config_file=WEBSITE_TEST_CONFIG)
        self.assert_defaults(wb)


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)

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


class TestWebsiteRsync(object):

    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, 'www')}"
            , '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
        homedir = os.path.join(tmpdir, "www")
        subdir = os.path.join(homedir, "subdir")
        file = os.path.join(subdir, "website_file")
        os.makedirs(homedir)
        os.makedirs(subdir)
        Path(file).touch()

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

        # check that the rsync is successful (with options)
        wb = WebsiteBackup(config, schema)

        expected_subdir_bck1 = os.path.join(tmpdir, 'backup_1_path', 'www', 'subdir')
        expected_file_bck1   = os.path.join(tmpdir, 'backup_1_path', 'www', 'subdir/website_file')
        expected_subdir_bck2 = os.path.join(tmpdir, 'backup_2_path', 'www', 'subdir')
        expected_file_bck2   = os.path.join(tmpdir, 'backup_2_path', 'www', 'subdir/website_file')
        assert not os.path.exists(expected_subdir_bck1)
        assert not os.path.exists(expected_file_bck1)
        assert not os.path.exists(expected_subdir_bck2)
        assert not os.path.exists(expected_file_bck2)
        wb._run_rsync()
        assert os.path.exists(expected_subdir_bck1)
        assert os.path.exists(expected_file_bck1)
        assert os.path.exists(expected_subdir_bck2)
        assert os.path.exists(expected_file_bck2)
