#!/usr/bin/python3

# checkpoint:
# 1. export blueprint package list (copy)
# 2. blueprint description edit/update
# 3. hostname setting
# 4. user setting
import composerlib
import testlib


@testlib.nondestructive
class TestCustom(composerlib.ComposerCase):

    def testDescription(self):
        b = self.browser
        m = self.machine

        self.login_and_go("/composer", superuser=True)
        b.wait_visible("#main")

        # go to blueprint openssh-server
        b.click("#openssh-server-name")

        # update description (cancel first)
        updated_description = "edit ssh server image description"
        with b.wait_timeout(300):
            b.click("a:contains('ssh server image')")
        b.wait_visible("#cmpsr-modal-edit-description")
        b.set_input_text("#textInput-modal-markup", updated_description)
        b.click("#cmpsr-modal-edit-description button:contains('Cancel')")
        b.wait_not_present("#cmpsr-modal-edit-description")
        b.wait_visible("a:contains('ssh server image')")

        # update description
        actions_drop_down_sel = ".cmpsr-header__actions #dropdownKebab"
        b.click(actions_drop_down_sel)
        b.wait_attr(actions_drop_down_sel, "aria-expanded", "true")
        b.click("a:contains('Edit description')")
        b.wait_visible("#cmpsr-modal-edit-description")
        b.set_input_text("#textInput-modal-markup", updated_description)
        b.click("#cmpsr-modal-edit-description button:contains('Save')")
        b.wait_not_present("#cmpsr-modal-edit-description")
        b.wait_visible("a:contains('{}')".format(updated_description))
        # backend got updated as well
        desc = m.execute("""
            composer-cli blueprints show openssh-server | grep description | \
            awk -F '"' '{print $2}'
            """).rstrip()
        self.assertEqual(desc, updated_description)

        # collect code coverage result
        self.check_coverage()

    def testHostname(self):
        b = self.browser
        m = self.machine

        self.login_and_go("/composer", superuser=True)
        b.wait_visible("#main")

        b.click("#openssh-server-name")
        with b.wait_timeout(300):
            b.click("#blueprint-tabs-tab-customizations")
        # set hostname to "openssh-server"
        b.click("button[aria-describedby=Hostname-help2]")
        b.set_input_text("input[aria-label=Hostname]", "hostname-openssh-server")
        b.click(".form-control-pf-save")
        b.wait_visible("span:contains(hostname-openssh-server)")
        hostname = m.execute("""
            composer-cli blueprints show openssh-server | grep hostname | awk -F '"' '{print $2}'
            """).rstrip()
        b.wait_visible("span:contains({})".format(hostname))

        # update hostname
        b.click(".form-control-pf-value")
        b.set_input_text("input[aria-label=Hostname]", "update-openssh-server")
        b.key_press("\r")
        b.wait_visible("span:contains(update-openssh-server)")
        hostname = m.execute("""
            composer-cli blueprints show openssh-server | grep hostname | awk -F '"' '{print $2}'
            """).rstrip()
        b.wait_visible("span:contains({})".format(hostname))

        # clicking x button will not update
        b.click(".form-control-pf-value")
        b.set_input_text("input[aria-label=Hostname]", "no-update-openssh-server")
        b.click(".form-control-pf-cancel")
        b.wait_visible("span:contains(update-openssh-server)")
        hostname = m.execute("""
            composer-cli blueprints show openssh-server | grep hostname | awk -F '"' '{print $2}'
            """).rstrip()
        b.wait_visible("span:contains({})".format(hostname))

        # invalid character, save button is disabled
        b.click(".form-control-pf-value")
        b.set_input_text("input[aria-label=Hostname]", "?")
        b.wait_attr(".form-control-pf-save", "disabled", "")

        # collect code coverage result
        self.check_coverage()

    def testUserAccount(self):
        b = self.browser

        # HACK: cockpit-composer may loose keystrokes, see issue #944
        def set_input_value(sel, val):
            w = ""
            for k in val:
                w += k
                while b.val(sel) != w:
                    b.focus(sel)
                    b.key_press(k)

        self.login_and_go("/composer", superuser=True)
        b.wait_visible("#main")

        b.click("#openssh-server-name")
        with b.wait_timeout(300):
            b.click("#blueprint-tabs-tab-customizations")

        # add a new user
        b.click("button:contains('Create user account')")
        b.wait_visible("#cmpsr-modal-user-account")
        set_input_value("#textInput2-modal-user", "user")
        b.wait_val("#textInput1-modal-user", "user")
        b.click("input[aria-label='Server admin checkbox']")
        set_input_value("#textInput1-modal-password", "fooBAR!@#123")
        set_input_value("#textInput2-modal-password", "fooBAR!@#123")
        ssh_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUOtNJdBEXyKxBB898rdT54ULjMGuO6v4" \
                  "jLXmRsdRhR5Id/lKNc9hsdioPWUePgYlqML2iSV72vKQoVhkyYkpcsjr3zvBny9+5xej3+T" \
                  "BLoEMAm2hmllKPmxYJDU8jQJ7wJuRrOVOnk0iSNF+FcY/yaQ0owSF02Nphx47j2KWc0IjGG" \
                  "lt4fl0fmHJuZBA2afN/4IYIIsEWZziDewVtaEjWV3InMRLllfdqGMllhFR+ed2hQz9PN2Qc" \
                  "apmEvUR4UCy/mJXrke5htyFyHi8ECfyMMyYeHwbWLFQIve4CWix9qtksvKjcetnxT+WWrut" \
                  "dr3c9cfIj/c0v/Zg/c4zETxtp cockpit-test"
        b.set_input_text("#textInput5-modal-user", ssh_key)
        b.click("#cmpsr-modal-user-account button:contains('Create')")
        b.wait_not_present("#cmpsr-modal-user-account")
        b.wait_text("tr td[data-label='Full name']", "user")
        b.wait_text("tr td[data-label='User name']", "user")
        b.wait_visible("tr td[data-label='Server administrator'] .fa-check")
        b.wait_visible("tr td[data-label='Password'] .fa-check")
        b.wait_visible("tr td[data-label='SSH key'] .fa-check")

        # update password
        new_password = "c456rty$%^RTY"
        b.click("button[aria-label='Edit user account user']")
        b.wait_visible("#cmpsr-modal-user-account")
        b.click("button:contains('Set new password')")
        set_input_value("#textInput1-modal-password", new_password)
        set_input_value("#textInput2-modal-password", new_password)
        b.click("#cmpsr-modal-user-account button:contains('Update')")
        b.wait_not_present("#cmpsr-modal-user-account")
        b.wait_visible("tr td[data-label=Password] .fa-check")

        # remove password
        b.click("button[aria-label='Edit user account user']")
        b.wait_visible("#cmpsr-modal-user-account")
        b.click("button:contains('Remove password')")
        b.click("#cmpsr-modal-user-account button:contains('Update')")
        b.wait_not_present("#cmpsr-modal-user-account")
        b.wait_visible("table[aria-label='Users List']")
        b.wait_not_present("tr td[data-label='Password'] .fa-check")

        # These tests are failing due to issues with the firefox nightly.
        # This is tracked in https://github.com/osbuild/cockpit-composer/issues/1336
        # # duplicated user
        # b.click("button:contains('Create user account')")
        # b.wait_visible("#cmpsr-modal-user-account")
        # set_input_value("#textInput2-modal-user", "user")
        # b.wait_in_text("#textInput1-modal-user-help1", "This user name already exists.")
        # b.click("#cmpsr-modal-user-account button:contains('Cancel')")
        # b.wait_not_present("#cmpsr-modal-user-account")

        # # password checking error
        # b.click("button:contains('Create user account')")
        # b.wait_visible("#cmpsr-modal-user-account")
        # set_input_value("#textInput2-modal-user", "admin user")
        # b.click("input[aria-label='Server admin checkbox']")
        # set_input_value("#textInput1-modal-password", "aaa")
        # set_input_value("#textInput2-modal-password", "bbb")
        # b.wait_in_text("#textInput2-modal-password-help",
        #                "The values entered for password do not match.")
        # b.click("#cmpsr-modal-user-account button:contains('Cancel')")
        # b.wait_not_present("#cmpsr-modal-user-account")

        # delete user
        delete_drop_down_sel = "button[aria-label='User account actions user']"
        b.click(delete_drop_down_sel)
        b.wait_attr(delete_drop_down_sel, "aria-expanded", "true")
        b.click("a:contains('Delete user account')")
        b.wait_not_present("table[aria-label='Users List']")

        # collect code coverage result
        self.check_coverage()


if __name__ == '__main__':
    testlib.test_main()
