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

from anacondalib import VirtInstallMachineCase, pixel_tests_ignore
from installer import Installer
from language import Language
from password import Password
from storage import Storage
from testlib import nondestructive, test_main  # pylint: disable=import-error


@nondestructive
class TestStorageEncryption(VirtInstallMachineCase):

    def set_valid_password(self, password_ui, password="abcdefgh"):
        password_ui.set_password(password)
        password_ui.set_password_confirm(password)

    def testEncryptionPassword(self):
        """
        Description:
            Verifies the password rules and strength indicators

        Expected results:
            - The password rules are shown correctly
            - The password strength is shown correctly
        """
        b = self.browser
        i = Installer(b, self.machine)
        l = Language(b, self.machine)
        s = Storage(b, self.machine)
        p = Password(b, s.encryption_id_prefix)

        i.open()

        # Language selection
        l.check_selected_locale("en_US")
        l.check_selected_keyboard("us")

        i.reach(i.steps.INSTALLATION_METHOD)

        # Check the default mode
        s.check_scenario_selected("erase-all")

        i.next()
        # Disk Encryption

        s.set_encryption_selected(False)
        i.check_next_disabled(False)

        # move the mouse away to avoid highlighting any UI element (pixel ref does not expect that)
        b.mouse("#app", "mouseenter")

        b.assert_pixels(
            "#app",
            "storage-step-encrypt",
            ignore=pixel_tests_ignore,
        )

        s.check_encryption_selected(False)
        encrypt = True
        s.set_encryption_selected(encrypt)

        b.wait_val("#disk-encryption-keyboard-layout", "us")
        # move the mouse away to avoid highlighting any UI element (pixel ref does not expect that)
        b.mouse("#app", "mouseenter")

        # Disk Encryption / password screen
        b.assert_pixels(
            "#app",
            "storage-step-password",
            ignore=pixel_tests_ignore,
        )

        # No password set
        p.check_pw_rule("length", "indeterminate")
        p.check_pw_rule("match", "indeterminate")
        i.check_next_disabled()

        # Set pw which is too short
        p.set_password("abcd")
        p.check_pw_strength(None)
        i.check_next_disabled()
        p.check_pw_rule("length", "error")
        p.check_pw_rule("match", "error")

        # Make the pw 8 chars long
        p.set_password("efgh", append=True, value_check=False)
        i.check_next_disabled()
        p.check_password("abcdefgh")
        p.check_pw_rule("length", "success")
        p.check_pw_rule("match", "error")
        p.check_pw_strength("weak")

        # Non-ASCII password
        p.set_password(8 * "š")
        p.check_password(8 * "š")
        p.check_pw_rule("length", "success")
        p.check_pw_rule("match", "error")
        p.check_pw_rule("ascii", "warning")
        p.check_pw_strength("weak")

        # Valid ASCII password
        p.set_password("abcdefgh")
        p.check_password("abcdefgh")

        # Set the password confirm
        p.set_password_confirm("abcdefg")
        p.check_pw_rule("match", "error")
        p.set_password_confirm("abcdefgh")
        p.check_pw_rule("match", "success")
        p.check_pw_rule("length", "success")
        p.check_pw_strength("weak")
        p.check_password("abcdefgh")
        p.check_password_confirm("abcdefgh")
        i.check_next_disabled(disabled=False)

        # Check setting strong password
        strong_password = "Rwce82ybF7dXtCzFumanchu!!!!!!!!"
        p.set_password(strong_password)
        p.check_password(strong_password)
        p.check_pw_strength("strong")
        p.set_password_confirm(strong_password)

    def testEncryptionPreserved(self):
        """
        Description:
            Check that the encryption details are preserved when moving
            back and forth between screens
        """
        b = self.browser
        i = Installer(b, self.machine)
        s = Storage(b, self.machine)
        p = Password(b, s.encryption_id_prefix)

        i.open()
        i.reach(i.steps.STORAGE_CONFIGURATION)
        # Disk Encryption / password screen

        encrypt = True
        s.set_encryption_selected(encrypt)
        s.check_encryption_selected(encrypt)

        # Set valid password
        self.set_valid_password(p)

        # Verify that the password is saved when moving forward and back
        i.next()
        i.back()
        s.check_encryption_selected(encrypt)
        p.check_password("abcdefgh")
        p.check_password_confirm("abcdefgh")

        # Verify that the password is saved when moving backward and forward
        i.back()
        i.next()
        s.check_encryption_selected(encrypt)
        p.check_password("abcdefgh")
        p.check_password_confirm("abcdefgh")


if __name__ == '__main__':
    test_main()
