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

import os
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):
        builldir = os.environ.get('BUILDDIR', './')
        bbv = BitbakeVersion.objects.create(name='bbv1', giturl=f'{builldir}/',
                                            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)
        self.wait_until_visible('#global-nav', poll=3)

    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)
