#!/usr/bin/python3
#
# Copyright (C) 2025 Red Hat, Inc.
# SPDX-License-Identifier: LGPL-2.1-or-later

from anacondalib import INSTALLER_VM_MEMORY_MB, VirtInstallMachineCase
from installer import Installer
from review import Review
from storage import Storage
from testlib import test_main, timeout  # pylint: disable=import-error


class TestStorageMountPointsBtrfs_E2E(VirtInstallMachineCase):
    provision = {"machine1": {"memory_mb": INSTALLER_VM_MEMORY_MB}}

    def _testPreserveHome_partition_disk(self):
        b = self.browser
        m = self.machine
        s = Storage(b, m)

        disk = "/dev/vda"
        tmp_mount = "/tmp/btrfs-mount-test"
        # GPT: 1: EFI, 2: btrfs volume
        s.partition_disk(disk, [("100MiB", "efi"), ("", "btrfs")])

        m.execute(f"""
        set -ex
        mkdir -p {tmp_mount}
        mount {disk}2 {tmp_mount}
        btrfs subvolume create {tmp_mount}/root
        btrfs subvolume create {tmp_mount}/home
        # Create a nested subvolume in root to test bug 2394554
        # First create the parent directories inside the root subvolume
        root_mount="{tmp_mount}/root_mount"
        mkdir -p "$root_mount"
        mount -o subvol=root {disk}2 "$root_mount"
        mkdir -p "$root_mount/var/lib"
        btrfs subvolume create "$root_mount/var/lib/machines"
        umount "$root_mount"
        rmdir "$root_mount"
        umount {tmp_mount}
        rmdir {tmp_mount}
        """)

    @timeout(1200)
    def testPreserveHome(self):
        """
        Description:
            EFI install using mount point assignment. Map / to btrfs subvolume 'root',
            preserve existing btrfs subvolume 'home'. The root subvolume contains a nested
            subvolume 'root/var/lib/machines' to test that dependent devices are properly
            handled when the parent is reformatted.

        Related bug:
            https://bugzilla.redhat.com/show_bug.cgi?id=2394554

        Expected results:
            - /boot/efi present
            - / on btrfs subvolume reformatted
            - /home preserved
            - Nested subvolume root/var/lib/machines is properly handled when root is reformatted
        """
        b = self.browser
        m = self.machine
        i = Installer(b, m)
        s = Storage(b, m)
        r = Review(b, m)

        dev = "vda"

        i.open()
        i.reach(i.steps.INSTALLATION_METHOD)

        # Select the disk and enter mount point mapping
        s.select_mountpoint([(dev, True)])

        # Assign root, efi, boot and home
        # Row 1: /
        s.select_mountpoint_row_device(1, "root")
        # Row 2: /boot or /boot/efi depending on firmware; we're EFI-only
        s.select_mountpoint_row_device(2, f"{dev}1")
        s.check_mountpoint_row_format_type(2, "EFI System Partition")

        s.remove_mountpoint_row(3, 3)  # Remove default /boot row

        # Add /home row, select home subvol, do NOT reformat
        s.add_mountpoint_row()
        s.select_mountpoint_row_device(3, "home")
        s.select_mountpoint_row_mountpoint(3, "/home")

        # Review and install
        i.next(should_fail=True)
        i.reach(i.steps.REVIEW)

        r.check_disk(dev, "16.1 GB vda (Virtio Block Device)")
        r.check_disk_row(dev, "/boot/efi", f"{dev}1", "105 MB", False)
        r.check_disk_row(dev, "/", f"{dev}2", "16.0 GB", True, "btrfs subvolume")
        r.check_disk_row(dev, "/home", f"{dev}2", "16.0 GB", False)

        self.install(button_text="Apply mount point assignment and install", needs_confirmation=True)

    def _testReformatBtrfsVolume_partition_disk(self):
        b = self.browser
        m = self.machine
        s = Storage(b, m)

        disk = "/dev/vda"
        # GPT: 1: EFI, 2: ext4 for /boot, 3: btrfs volume for /
        s.partition_disk(disk, [("100MiB", "efi"), ("1GiB", "ext4"), ("", "btrfs")])

        # Create a btrfs volume (not subvolume!) on partition 3 with label "root"
        # This is key - we're creating a BTRFS volume, not subvolumes within it
        # The bug occurs when reformatting a BTRFS volume (which changes its UUID)
        # Use -f to force overwrite since partition_disk already created a btrfs filesystem
        m.execute(f"""
        set -ex
        mkfs.btrfs -f -L root {disk}3
        """)

    @timeout(1200)
    def testReformatBtrfsVolume(self):
        """
        Description:
            EFI install using mount point assignment. Reformat a BTRFS volume
            (not subvolume) and assign it to /. This tests the scenario where
            the BTRFS volume UUID changes during reformatting.

        Related bug:
            https://bugzilla.redhat.com/show_bug.cgi?id=2496875

        Expected results:
            - /boot/efi present
            - /boot on ext4 partition
            - / on reformatted btrfs volume
            - No error when generating kickstart after reformatting BTRFS volume
        """
        b = self.browser
        m = self.machine
        i = Installer(b, m)
        s = Storage(b, m)

        dev = "vda"

        i.open()
        i.reach(i.steps.INSTALLATION_METHOD)

        # Select the disk and enter mount point mapping
        s.select_mountpoint([(dev, True)])

        # Assign mount points
        # Row 1: / on vda3 (btrfs volume)
        s.select_mountpoint_row_device(1, "root")
        # Enable reformat - this is what triggers the bug
        s.select_mountpoint_row_reformat(1, True)

        # Row 2: /boot/efi on vda1
        s.select_mountpoint_row_device(2, f"{dev}1")
        s.check_mountpoint_row_format_type(2, "EFI System Partition")

        # Row 3: /boot on vda2 (ext4)
        s.select_mountpoint_row_device(3, f"{dev}2")
        s.select_mountpoint_row_reformat(3, True)

        # Review and install
        i.next(should_fail=True)
        i.reach(i.steps.REVIEW)

        self.install(button_text="Apply mount point assignment and install", needs_confirmation=True)


if __name__ == '__main__':
    test_main()
