import pytest
import shutil
from calculate.templates.format.patch_format import PatchFormat
from calculate.utils.files import Process
from os import path
import os
import re


BACKUP_PATH = os.path.join(os.getcwd(),
                           'tests/templates/format/'
                           'testfiles/patch/root.backup')

TEST_ROOT_PATH = os.path.join(os.getcwd(),
                              'tests/templates/format/testfiles/patch/root')


@pytest.mark.patch
class TestExecuteMethods:
    def test_create_testfiles(self):
        shutil.copytree(BACKUP_PATH, TEST_ROOT_PATH)

    def test_if_diff_patch_used_for_patching_of_several_files__it_changes_patched_file_correctly(self):
        if not os.path.exists(TEST_ROOT_PATH):
            assert False

        path_pattern = re.compile(r'/a1/')
        test_result = True
        cwd_path = path.join(os.getcwd(),
                             'tests/templates/format/testfiles/patch/root')
        with open(path.join(cwd_path, 'diff_1.patch')) as patch_file:
            patch_text = patch_file.read()

        diff_patch = PatchFormat(patch_text, '/template/path')
        output = diff_patch.execute_format(target_path=cwd_path)
        if output:
            for changed_file, change_type in diff_patch.changed_files.items():
                with open(changed_file, 'r') as patched_file:
                    patched_file_text = patched_file.read()

                other_file_path = re.sub(path_pattern, '/b/', changed_file)
                with open(other_file_path, 'r') as other_file:
                    other_file_text = other_file.read()
                test_result = (test_result and (other_file_text
                               == patched_file_text))
        else:
            test_result = False
        assert test_result

    def test_if_diff_patch_used_for_patching_of_directories__it_changes_files_in_directories_and_adds_ones(self):
        if not os.path.exists(TEST_ROOT_PATH):
            assert False

        path_pattern = re.compile(r'/a1/')
        test_result = True
        cwd_path = path.join(
                         os.getcwd(),
                         'tests/templates/format/testfiles/patch/root/a1')
        patch_path = path.join(
               os.getcwd(),
               'tests/templates/format/testfiles/patch/root/diff_2.patch')
        with open(path.join(patch_path)) as patch_file:
            patch_text = patch_file.read()

        diff_patch = PatchFormat(patch_text, '/template/path')
        diff_patch.execute_format(target_path=cwd_path)

        for changed_file, change_type in diff_patch.changed_files.items():
            with open(changed_file, 'r') as patched_file:
                patched_file_text = patched_file.read()

            other_file_path = re.sub(path_pattern, '/b1/', changed_file)
            with open(other_file_path) as other_file:
                other_file_text = other_file.read()
            test_result = (test_result and (other_file_text
                           == patched_file_text))
        assert test_result

    def test_remove_testfiles(self):
        shutil.rmtree(TEST_ROOT_PATH)
