#! /usr/bin/env python3
#
# BitBake Toaster Implementation
#
# Copyright (C) 2013-2016 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
#

from django.urls import reverse
from django.utils import timezone

from tests.browser.selenium_helpers import SeleniumTestCase

from orm.models import Project, Release, BitbakeVersion, Build, LogMessage
from orm.models import Layer, Layer_Version, Recipe, CustomImageRecipe, Variable

from selenium.webdriver.common.by import By

class TestBuildDashboardPage(SeleniumTestCase):
    """ Tests for the build dashboard /build/X """

    def setUp(self):
        bbv = BitbakeVersion.objects.create(name='bbv1', giturl='/tmp/',
                                            branch='master', dirpath="")
        release = Release.objects.create(name='release1',
                                         bitbake_version=bbv)
        project = Project.objects.create_project(name='test project',
                                                 release=release)

        now = timezone.now()

        self.build1 = Build.objects.create(project=project,
                                           started_on=now,
                                           completed_on=now,
                                           outcome=Build.SUCCEEDED)

        self.build2 = Build.objects.create(project=project,
                                           started_on=now,
                                           completed_on=now,
                                           outcome=Build.SUCCEEDED)

        self.build3 = Build.objects.create(project=project,
                                           started_on=now,
                                           completed_on=now,
                                           outcome=Build.FAILED)

        # add Variable objects to the successful builds, as this is the criterion
        # used to determine whether the left-hand panel should be displayed
        Variable.objects.create(build=self.build1,
                                variable_name='Foo',
                                variable_value='Bar')
        Variable.objects.create(build=self.build2,
                                variable_name='Foo',
                                variable_value='Bar')

        # exception
        msg1 = 'an exception was thrown'
        self.exception_message = LogMessage.objects.create(
            build=self.build1,
            level=LogMessage.EXCEPTION,
            message=msg1
        )

        # critical
        msg2 = 'a critical error occurred'
        self.critical_message = LogMessage.objects.create(
            build=self.build1,
            level=LogMessage.CRITICAL,
            message=msg2
        )

        # error on the failed build
        msg3 = 'an error occurred'
        self.error_message = LogMessage.objects.create(
            build=self.build3,
            level=LogMessage.ERROR,
            message=msg3
        )

        # warning on the failed build
        msg4 = 'DANGER WILL ROBINSON'
        self.warning_message = LogMessage.objects.create(
            build=self.build3,
            level=LogMessage.WARNING,
            message=msg4
        )

        # recipes related to the build, for testing the edit custom image/new
        # custom image buttons
        layer = Layer.objects.create(name='alayer')
        layer_version = Layer_Version.objects.create(
            layer=layer, build=self.build1
        )

        # non-image recipes related to a build, for testing the new custom
        # image button
        layer_version2 = Layer_Version.objects.create(layer=layer,
            build=self.build3)

        # image recipes
        self.image_recipe1 = Recipe.objects.create(
            name='recipeA',
            layer_version=layer_version,
            file_path='/foo/recipeA.bb',
            is_image=True
        )
        self.image_recipe2 = Recipe.objects.create(
            name='recipeB',
            layer_version=layer_version,
            file_path='/foo/recipeB.bb',
            is_image=True
        )

        # custom image recipes for this project
        self.custom_image_recipe1 = CustomImageRecipe.objects.create(
            name='customRecipeY',
            project=project,
            layer_version=layer_version,
            file_path='/foo/customRecipeY.bb',
            base_recipe=self.image_recipe1,
            is_image=True
        )
        self.custom_image_recipe2 = CustomImageRecipe.objects.create(
            name='customRecipeZ',
            project=project,
            layer_version=layer_version,
            file_path='/foo/customRecipeZ.bb',
            base_recipe=self.image_recipe2,
            is_image=True
        )

        # custom image recipe for a different project (to test filtering
        # of image recipes and custom image recipes is correct: this shouldn't
        # show up in either query against self.build1)
        self.custom_image_recipe3 = CustomImageRecipe.objects.create(
            name='customRecipeOmega',
            project=Project.objects.create(name='baz', release=release),
            layer_version=Layer_Version.objects.create(
                layer=layer, build=self.build2
            ),
            file_path='/foo/customRecipeOmega.bb',
            base_recipe=self.image_recipe2,
            is_image=True
        )

        # another non-image recipe (to test filtering of image recipes and
        # custom image recipes is correct: this shouldn't show up in either
        # for any build)
        self.non_image_recipe = Recipe.objects.create(
            name='nonImageRecipe',
            layer_version=layer_version,
            file_path='/foo/nonImageRecipe.bb',
            is_image=False
        )

    def _get_build_dashboard(self, build):
        """
        Navigate to the build dashboard for build
        """
        url = reverse('builddashboard', args=(build.id,))
        self.get(url)

    def _get_build_dashboard_errors(self, build):
        """
        Get a list of HTML fragments representing the errors on the
        dashboard for the Build object build
        """
        self._get_build_dashboard(build)
        return self.find_all('#errors div.alert-danger')

    def _check_for_log_message(self, message_elements, log_message):
        """
        Check that the LogMessage <log_message> has a representation in
        the HTML elements <message_elements>.

        message_elements: WebElements representing the log messages shown
        in the build dashboard; each should have a <pre> element inside
        it with a data-log-message-id attribute

        log_message: orm.models.LogMessage instance
        """
        expected_text = log_message.message
        expected_pk = str(log_message.pk)

        found = False
        for element in message_elements:
            log_message_text = element.find_element(By.TAG_NAME, 'pre').text.strip()
            text_matches = (log_message_text == expected_text)

            log_message_pk = element.get_attribute('data-log-message-id')
            id_matches = (log_message_pk == expected_pk)

            if text_matches and id_matches:
                found = True
                break

        template_vars = (expected_text, expected_pk)
        assertion_failed_msg = 'message not found: ' \
            'expected text "%s" and ID %s' % template_vars
        self.assertTrue(found, assertion_failed_msg)

    def _check_for_error_message(self, build, log_message):
        """
        Check whether the LogMessage instance <log_message> is
        represented as an HTML error in the dashboard page for the Build object
        build
        """
        errors = self._get_build_dashboard_errors(build)
        self._check_for_log_message(errors, log_message)

    def _check_labels_in_modal(self, modal, expected):
        """
        Check that the text values of the <label> elements inside
        the WebElement modal match the list of text values in expected
        """
        # labels containing the radio buttons we're testing for
        labels = modal.find_elements(By.CSS_SELECTOR,".radio")

        labels_text = [lab.text for lab in labels]
        self.assertEqual(len(labels_text), len(expected))

        for expected_text in expected:
            self.assertTrue(expected_text in labels_text,
                            "Could not find %s in %s" % (expected_text,
                                                         labels_text))

    def test_exceptions_show_as_errors(self):
        """
        LogMessages with level EXCEPTION should display in the errors
        section of the page
        """
        self._check_for_error_message(self.build1, self.exception_message)

    def test_criticals_show_as_errors(self):
        """
        LogMessages with level CRITICAL should display in the errors
        section of the page
        """
        self._check_for_error_message(self.build1, self.critical_message)

    def test_edit_custom_image_button(self):
        """
        A build which built two custom images should present a modal which lets
        the user choose one of them to edit
        """
        self._get_build_dashboard(self.build1)

        # click the "edit custom image" button, which populates the modal
        selector = '[data-role="edit-custom-image-trigger"]'
        self.click(selector)

        modal = self.driver.find_element(By.ID, 'edit-custom-image-modal')
        self.wait_until_visible("#edit-custom-image-modal")

        # recipes we expect to see in the edit custom image modal
        expected_recipes = [
            self.custom_image_recipe1.name,
            self.custom_image_recipe2.name
        ]

        self._check_labels_in_modal(modal, expected_recipes)

    def test_new_custom_image_button(self):
        """
        Check that a build with multiple images and custom images presents
        all of them as options for creating a new custom image from
        """
        self._get_build_dashboard(self.build1)

        # click the "new custom image" button, which populates the modal
        selector = '[data-role="new-custom-image-trigger"]'
        self.click(selector)

        modal = self.driver.find_element(By.ID,'new-custom-image-modal')
        self.wait_until_visible("#new-custom-image-modal")

        # recipes we expect to see in the new custom image modal
        expected_recipes = [
            self.image_recipe1.name,
            self.image_recipe2.name,
            self.custom_image_recipe1.name,
            self.custom_image_recipe2.name
        ]

        self._check_labels_in_modal(modal, expected_recipes)

    def test_new_custom_image_button_no_image(self):
        """
        Check that a build which builds non-image recipes doesn't show
        the new custom image button on the dashboard.
        """
        self._get_build_dashboard(self.build3)
        selector = '[data-role="new-custom-image-trigger"]'
        self.assertFalse(self.element_exists(selector),
            'new custom image button should not show for builds which ' \
            'don\'t have any image recipes')

    def test_left_panel(self):
        """"
        Builds which succeed should have a left panel and a build summary
        """
        self._get_build_dashboard(self.build1)

        left_panel = self.find_all('#nav')
        self.assertEqual(len(left_panel), 1)

        build_summary = self.find_all('[data-role="build-summary-heading"]')
        self.assertEqual(len(build_summary), 1)

    def test_failed_no_left_panel(self):
        """
        Builds which fail should have no left panel and no build summary
        """
        self._get_build_dashboard(self.build3)

        left_panel = self.find_all('#nav')
        self.assertEqual(len(left_panel), 0)

        build_summary = self.find_all('[data-role="build-summary-heading"]')
        self.assertEqual(len(build_summary), 0)

    def test_failed_shows_errors_and_warnings(self):
        """
        Failed builds should still show error and warning messages
        """
        self._get_build_dashboard(self.build3)

        errors = self.find_all('#errors div.alert-danger')
        self._check_for_log_message(errors, self.error_message)

        # expand the warnings area
        self.click('#warning-toggle')
        self.wait_until_visible('#warnings div.alert-warning')

        warnings = self.find_all('#warnings div.alert-warning')
        self._check_for_log_message(warnings, self.warning_message)
