#!/usr/bin/python3

# checkpoint:
# 1. create blueprint
# 2. blueprint filter
# 3. blueprint sort

import composerlib
import testlib


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

    def testCreate(self):
        b = self.browser

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

        bp_name = "bp_name"
        bp_desc = "bp_description"
        b.click("#cmpsr-btn-crt-blueprint")
        b.wait_visible("#cmpsr-modal-crt-blueprint")
        # blueprint name
        b.set_input_text("#textInput-modal-markup", bp_name)
        # blueprint description
        b.set_input_text("#textInput2-modal-markup", bp_desc)
        # create
        b.click("#create-blueprint-modal-create-button")
        b.wait_not_present("#cmpsr-modal-crt-blueprint")

        # wait for back to blueprint link and click
        b.wait_visible("a:contains('Back to blueprints')")
        b.click("a:contains('Back to blueprints')")

        # new added blueprint should be there with correct name and description
        b.wait_visible("li[data-blueprint={}]".format(bp_name))
        b.wait_text("#{}-name".format(bp_name), bp_name)
        b.wait_text("li[data-blueprint={}] div[data-description]".format(bp_name), bp_desc)

        # delete blueprint, cancel first
        dropdown = "div[rowid={}-name] .pf-c-dropdown ".format(bp_name)
        b.click(dropdown + ".pf-c-dropdown__toggle")
        b.click(dropdown + ".pf-c-dropdown__menu a:contains('Delete')")
        b.click("#cmpsr-modal-delete button:contains('Cancel')")
        b.wait_not_present("#cmpsr-modal-delete")
        # delete here
        b.click(dropdown + ".pf-c-dropdown__toggle")
        b.click(dropdown + ".pf-c-dropdown__menu a:contains('Delete')")
        b.click("#cmpsr-modal-delete button:contains('Delete')")
        b.wait_not_present("#cmpsr-modal-delete")
        b.wait_not_present("li[data-blueprint={}]".format(bp_name))

        # collect code coverage result
        self.check_coverage()

    def testCreateValidation(self):
        b = self.browser

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

        # create blueprint
        b.click("#cmpsr-btn-crt-blueprint")
        b.wait_visible("#cmpsr-modal-crt-blueprint")
        # empty name blueprint
        b.set_input_text("#textInput-modal-markup", "")
        b.set_input_text("#textInput2-modal-markup", "test")
        # should have error message and disable Create button
        b.wait_text("#cmpsr-modal-crt-blueprint .help-block", "A blueprint name is required.")
        b.wait_attr("#create-blueprint-modal-create-button", "disabled", "")
        b.click("#cmpsr-modal-crt-blueprint button:contains('Cancel')")
        b.wait_not_present("#cmpsr-modal-crt-blueprint")

        # invalid characters for blueprint name
        b.click("#cmpsr-btn-crt-blueprint")
        b.wait_visible("#cmpsr-modal-crt-blueprint")
        # empty name blueprint
        b.set_input_text("#textInput-modal-markup", " /=*#$!'")
        b.wait_text("#cmpsr-modal-crt-blueprint .help-block",
                    "Blueprint names cannot contain spaces or the characters: / = * # $ ! '")
        b.click("#cmpsr-modal-crt-blueprint button[aria-label=Close]")
        b.wait_not_present("#cmpsr-modal-crt-blueprint")

        # duplicate name
        # wait until the openssh-server blueprint is there
        b.wait_in_text("ul[aria-label=Blueprints]", "openssh-server")
        b.click("#cmpsr-btn-crt-blueprint")
        b.wait_visible("#cmpsr-modal-crt-blueprint")
        # empty name blueprint
        b.set_input_text("#textInput-modal-markup", "openssh-server")
        b.set_input_text("#textInput2-modal-markup", "openssh server image")
        b.wait_text("#cmpsr-modal-crt-blueprint .help-block",
                    "The name openssh-server already exists.")
        b.click("#cmpsr-modal-crt-blueprint button:contains('Cancel')")
        b.wait_not_present("#cmpsr-modal-crt-blueprint")

        # duplicate name (by pressing enter)
        # wait until the openssh-server blueprint is there
        b.wait_in_text("ul[aria-label=Blueprints]", "openssh-server")
        b.click("#cmpsr-btn-crt-blueprint")
        b.wait_visible("#cmpsr-modal-crt-blueprint")
        # empty name blueprint
        b.set_input_text("#textInput-modal-markup", "openssh-server", blur=False)
        b.key_press("\r")
        b.wait_text("#cmpsr-modal-crt-blueprint .alert-danger", "Specify a new blueprint name.")
        b.click("#cmpsr-modal-crt-blueprint button:contains('Cancel')")
        b.wait_not_present("#cmpsr-modal-crt-blueprint")

        # collect code coverage result
        self.check_coverage()

    def testFilter(self):
        b = self.browser

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

        # filter "openssh-server" blueprint
        b.focus("input[aria-label='blueprints search input']")
        b.key_press("openssh")
        b.key_press("\r")
        b.wait_visible("#openssh-server-name")
        b.wait_not_present("#httpd-server-name")
        # clear filter
        b.click(".pf-c-search-input__clear button")
        b.wait_visible("#httpd-server-name")

        # filter "httpd" will show three matched blueprints
        b.focus("input[aria-label='blueprints search input']")
        b.key_press("httpd")
        b.key_press("\r")
        b.wait_not_present("#openssh-server-name")
        b.wait_visible("#httpd-server-name")
        b.wait_visible("#httpd-server-with-hostname-name")
        b.wait_visible("#httpd-server-with-user-name")
        # clear filter
        b.click(".pf-c-search-input__clear button")
        b.wait_visible("#openssh-server-name")

        # collect code coverage result
        self.check_coverage()

    def testSort(self):
        b = self.browser

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

        blueprint_list = [
            "httpd-server",
            "httpd-server-with-hostname",
            "httpd-server-with-user",
            "openssh-server"
        ]
        # sort from Z-A
        b.wait_visible("ul[aria-label=Blueprints]")
        b.click("button[aria-label='sort ascending']")
        b.wait_visible("button[aria-label='sort descending']")
        for i, v in enumerate(sorted(blueprint_list, reverse=True)):
            b.wait_text("ul[aria-label=Blueprints] li:nth-child({}) a strong".format(i + 1), v)

        # sort from A-Z
        b.click("button[aria-label='sort descending']")
        b.wait_visible("button[aria-label='sort ascending']")
        for i, v in enumerate(sorted(blueprint_list)):
            b.wait_text("ul[aria-label=Blueprints] li:nth-child({}) a strong".format(i + 1), v)

        # collect code coverage result
        self.check_coverage()

    def testExport(self):
        b = self.browser

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

        # export package list
        dropdown = "div[rowid='openssh-server-name'] .pf-c-dropdown "
        b.click(dropdown + ".pf-c-dropdown__toggle")
        b.click(dropdown + ".pf-c-dropdown__menu a:contains('Export')")
        b.wait_visible("#cmpsr-modal-export")
        with b.wait_timeout(300):
            b.wait_in_text("#textInput2-modal-markup", "openssh-server")
        b.click("#cmpsr-modal-export button:contains('Copy')")

        # collect code coverage result
        self.check_coverage()


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