#!/usr/bin/python3

# This file is part of Cockpit.
#
# Copyright (C) 2017 Red Hat, Inc.
#
# Cockpit is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Cockpit is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.

import parent
from testlib import *
from machine_core.constants import TEST_OS_DEFAULT


@skipImage("Do not test BaseOS packages", "rhel-8-3-distropkg", "rhel-8-4-distropkg")
class TestActivePages(MachineCase):

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

        self.login_and_go("/system")

        # Preloading via manifests only happens with #12534
        if m.ostree_image:
            # /playground/preloaded and /system/services
            n_extra_preloaded = 2
        elif m.image == TEST_OS_DEFAULT:
            # /playground/preloaded
            n_extra_preloaded = 1
        else:
            # /playground/preloaded, /system/services, and /updates
            n_extra_preloaded = 3

        b.wait_visible("#overview")

        def showPagesAssertCount(count):
            b.switch_to_top()
            b.mouse("#navbar-dropdown", "click", altKey=True)
            b.click("#active-pages")
            b.wait_visible("#active-pages-dialog")
            b.wait_js_func("ph_count_check", "#active-pages-dialog tr", count)

        # Initially we have /system and maybe /playground/preloaded
        showPagesAssertCount(1 + n_extra_preloaded)
        b.click("button.cancel")
        b.wait_not_present("#active-pages-dialog")

        b.go("/users")
        b.enter_page("/users")
        b.wait_visible("#accounts-list")

        # now we want a third page to be present in the pages menu
        showPagesAssertCount(2 + n_extra_preloaded)
        b.click("button.cancel")
        b.wait_not_present("#active-pages-dialog")

        # open the terminal page and start a session we can see on the machine
        b.go("/system/terminal")
        b.enter_page("/system/terminal")

        b.focus(".terminal")

        def line_sel(i):
            return '.terminal .xterm-accessibility-tree div:nth-child(%d)' % i

        def line_text(t):
            return t + u'\xa0' * (80 - len(t))

        # wait for prompt in first line
        b.wait_text_not(line_sel(1), line_text(""))

        # run the sleep command
        b.key_press("sleep 999999\r")

        # wait for it to be present in ps
        wait(lambda: m.execute("ps ax | grep 'sleep 99.*999'"))

        # now close the page
        showPagesAssertCount(3 + n_extra_preloaded)

        # click on the other page as well
        b.click('tr[data-row-id="cockpit1:localhost/system"] input[type=checkbox]')
        # wait until it's highlighted
        b.wait_visible('tr[data-row-id="cockpit1:localhost/system"] input[type=checkbox]:checked')
        # close
        b.click("#active-pages-dialog button.pf-m-primary")
        b.wait_not_present("#active-pages-dialog")

        # running shell command should disappear on the system
        wait(lambda: m.execute("ps ax | grep 'sleep 99.*999'"))

        # there should only be the original pages left
        showPagesAssertCount(1 + n_extra_preloaded)


if __name__ == '__main__':
    test_main()
