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

from django.core.urlresolvers 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

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)
