import shutil
import unittest
from pathlib import Path

from src.backup_manager import BackupManager


class TestBackupManager(unittest.TestCase):
    """
    Unit tests for the BackupManager class, including nested directories.
    """

    def setUp(self):
        """
        Create temporary directories and files for testing, including subdirectories.
        """
        self.source_dir = Path("test_source")
        self.source_dir.mkdir(exist_ok=True)

        self.backup_file = Path("backup.zst")
        self.restore_dir = Path("test_restore")
        self.restore_dir.mkdir(exist_ok=True)
        self.encryption_key_path = Path("encryption.key")

        self.create_dummy_files()

        self.manager = BackupManager(self.source_dir, self.backup_file)

    def create_dummy_files(self):
        # Create a file in the root source directory
        self.test_file = self.source_dir / "test_file.txt"
        with open(self.test_file, "w") as f:
            f.write("This is a test file.")

        # Create a subdirectory with additional test files
        self.sub_dir = self.source_dir / "subdir"
        self.sub_dir.mkdir(exist_ok=True)

        self.sub_file = self.sub_dir / "sub_test_file.txt"
        with open(self.sub_file, "w") as f:
            f.write("This is a test file inside a subdirectory.")

    def tearDown(self):
        """
        Remove temporary directories and files after testing.
        """
        shutil.rmtree(self.source_dir, ignore_errors=True)
        shutil.rmtree(self.restore_dir, ignore_errors=True)
        if self.backup_file.exists():
            self.backup_file.unlink()
        if self.encryption_key_path.exists():
            self.encryption_key_path.unlink()

    def test_create_restore_backup(self):
        """
        Test creating and restoring a backup, including files in subdirectories.
        """
        self.manager.create_backup()

        self.assertTrue(self.backup_file.exists(), "Backup file should be created.")
        self.assertGreater(self.backup_file.stat().st_size, 0, "Backup file should not be empty.")

        self.manager.restore_backup(self.restore_dir)

        restored_file = self.restore_dir / self.source_dir / "test_file.txt"
        restored_sub_file = self.restore_dir / self.source_dir / "subdir" / "sub_test_file.txt"

        self.assertTrue(restored_file.exists(), "Restored file should exist.")
        self.assertTrue(restored_sub_file.exists(), "Restored subdirectory file should exist.")

        with open(restored_file, "r") as f:
            content = f.read()

        self.assertEqual(content, "This is a test file.", "Restored content should match the original.")

        with open(restored_sub_file, "r") as f:
            sub_content = f.read()

        self.assertEqual(
            sub_content,
            "This is a test file inside a subdirectory.",
            "Restored subdirectory file content should match the original.",
        )
