# Copyright (C) 2018-2019 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from __future__ import unicode_literals

import datetime
import re

from django.http import HttpResponse
from django.shortcuts import render
from django.utils import timezone
from django.views import View
from django.views.decorators.clickjacking import xframe_options_exempt
from ews.common.buildbot import Buildbot
from ews.models.build import Build
from ews.models.patch import Patch
import ews.config as config


class StatusBubble(View):
    # These queue names are from shortname in https://trac.webkit.org/browser/webkit/trunk/Tools/BuildSlaveSupport/ews-build/config.json
    # FIXME: Auto-generate this list https://bugs.webkit.org/show_bug.cgi?id=195640
    ALL_QUEUES = ['api-ios', 'api-mac', 'bindings', 'gtk', 'ios', 'ios-sim', 'ios-wk2', 'jsc', 'mac', 'mac-32bit', 'mac-32bit-wk2',
                    'mac-debug', 'mac-debug-wk1', 'mac-wk1', 'mac-wk2', 'style', 'webkitperl', 'webkitpy', 'win', 'wincairo', 'wpe']
    ENABLED_QUEUES = ['api-ios', 'api-mac', 'bindings', 'webkitperl', 'webkitpy']
    # FIXME: Auto-generate the queue's trigger relationship
    QUEUE_TRIGGERS = {
        'api-ios': 'ios-sim',
        'api-mac': 'mac',
    }

    STEPS_TO_HIDE = ['Killed old processes', 'Configured build', '^OS:.*Xcode:', '(skipped)']

    def _build_bubble(self, patch, queue):
        bubble = {
            'name': queue,
        }
        build, is_parent_build = self.get_latest_build_for_queue(patch, queue, self._get_parent_queue(queue))
        if not self._should_show_bubble_for_build(build):
            return None

        if not build:
            bubble['state'] = 'none'
            queue_position = self._queue_position(patch, queue, self._get_parent_queue(queue))
            bubble['queue_position'] = queue_position
            if not queue_position:
                return None
            bubble['details_message'] = 'Waiting in queue, processing has not started yet.\n\nPosition in queue: {}'.format(queue_position)
            return bubble

        bubble['url'] = 'https://{}/#/builders/{}/builds/{}'.format(config.BUILDBOT_SERVER_HOST, build.builder_id, build.number)
        builder_full_name = build.builder_name.replace('-', ' ')

        if build.result is None:  # In-progress build
            if self._does_build_contains_any_failed_step(build):
                bubble['state'] = 'provisional-fail'
            else:
                bubble['state'] = 'started'
            bubble['details_message'] = 'Build is in-progress. Recent messages:\n\n' + self._steps_messages(build)
        elif build.result == Buildbot.SUCCESS:
            if is_parent_build:
                bubble['state'] = 'started'
                bubble['details_message'] = 'Build is in-progress. Recent messages:\n\n' + self._steps_messages(build) + '\n\nWaiting to run tests.'
            else:
                bubble['state'] = 'pass'
                bubble['details_message'] = 'Pass'
        elif build.result == Buildbot.WARNINGS:
            bubble['state'] = 'pass'
            bubble['details_message'] = 'Warning\n\n' + self._steps_messages(build)
        elif build.result == Buildbot.FAILURE:
            bubble['state'] = 'fail'
            bubble['details_message'] = self._most_recent_step_message(build)
        elif build.result == Buildbot.SKIPPED:
            bubble['state'] = 'none'
            bubble['details_message'] = 'The patch is no longer eligible for processing.'
            if re.search(r'Bug .* is already closed', build.state_string):
                bubble['details_message'] += ' Bug was already closed when EWS attempted to process it.'
            elif re.search(r'Patch .* is marked r-', build.state_string):
                bubble['details_message'] += ' Patch was already marked r- when EWS attempted to process it.'
            elif re.search(r'Patch .* is obsolete', build.state_string):
                bubble['details_message'] += ' Patch was obsolete when EWS attempted to process it.'
            bubble['details_message'] += '\nSome messages were logged while the patch was still eligible:\n\n'
            bubble['details_message'] += self._steps_messages(build)

        elif build.result == Buildbot.EXCEPTION:
            bubble['state'] = 'error'
            bubble['details_message'] = 'An unexpected error occured. Recent messages:\n\n' + self._steps_messages(build)
        elif build.result == Buildbot.RETRY:
            bubble['state'] = 'provisional-fail'
            bubble['details_message'] = 'Build is being retried. Recent messages:\n\n' + self._steps_messages(build)
        elif build.result == Buildbot.CANCELLED:
            bubble['state'] = 'provisional-fail'
            bubble['details_message'] = 'Build was cancelled. Recent messages:\n\n' + self._steps_messages(build)
        else:
            bubble['state'] = 'error'
            bubble['details_message'] = 'An unexpected error occured. Recent messages:\n\n' + self._steps_messages(build)

        if 'details_message' in bubble:
            bubble['details_message'] = builder_full_name + '\n\n' + bubble['details_message']
            os_details = self.get_os_details(build)
            timestamp = self.get_build_timestamp(build)
            if os_details:
                bubble['details_message'] += '\n\n' + os_details + '\n' + timestamp
            else:
                bubble['details_message'] += '\n\n' + timestamp

        return bubble

    def _get_parent_queue(self, queue):
        return StatusBubble.QUEUE_TRIGGERS.get(queue)

    def get_os_details(self, build):
        for step in build.step_set.all():
            if step.state_string.startswith('OS:'):
                return step.state_string
        return ''

    def get_build_timestamp(self, build):
        if build.complete_at:
            return self._iso_time(build.complete_at)

        recent_build_step = build.step_set.last()
        if recent_build_step:
            return self._iso_time(recent_build_step.started_at)

        return self._iso_time(build.started_at)

    def _iso_time(self, time):
        return '[[' + datetime.datetime.fromtimestamp(time).isoformat() + 'Z]]'

    def _steps_messages(self, build):
        return '\n'.join([step.state_string for step in build.step_set.all().order_by('uid') if self._should_display_step(step)])

    def _should_display_step(self, step):
        return not filter(lambda step_to_hide: re.search(step_to_hide, step.state_string), StatusBubble.STEPS_TO_HIDE)

    def _does_build_contains_any_failed_step(self, build):
        for step in build.step_set.all():
            if step.result and step.result != Buildbot.SUCCESS:
                return True
        return False

    def _most_recent_step_message(self, build):
        recent_step = build.step_set.last()
        if not recent_step:
            return ''
        return recent_step.state_string

    def get_latest_build_for_queue(self, patch, queue, parent_queue=None):
        builds = self.get_builds_for_queue(patch, queue)
        is_parent_build = False
        if not builds and parent_queue:
            builds = self.get_builds_for_queue(patch, parent_queue)
            is_parent_build = True
        if not builds:
            return (None, None)
        builds.sort(key=lambda build: build.started_at, reverse=True)
        return (builds[0], is_parent_build)

    def get_builds_for_queue(self, patch, queue):
        return [build for build in patch.build_set.all() if build.builder_display_name == queue]

    def _should_show_bubble_for_build(self, build):
        if build and build.result == Buildbot.SKIPPED and re.search(r'Patch .* doesn\'t have relevant changes', build.state_string):
            return False
        return True

    def _should_show_bubble_for_queue(self, queue):
        return queue in StatusBubble.ENABLED_QUEUES

    def _queue_position(self, patch, queue, parent_queue=None):
        # FIXME: Handle retried builds and cancelled build-requests as well.
        DAYS_TO_CHECK = 3
        from_timestamp = timezone.now() - datetime.timedelta(days=DAYS_TO_CHECK)

        if patch.modified < from_timestamp:
            # Do not display bubble for old patch for which no build has been reported on given queue.
            # Most likely the patch would never be processed on this queue, since either the queue was
            # added after the patch was submitted, or build request for that patch was cancelled.
            return None

        previously_sent_patches = set(Patch.objects
                                          .filter(modified__gte=from_timestamp)
                                          .filter(sent_to_buildbot=True)
                                          .filter(obsolete=False)
                                          .filter(modified__lt=patch.modified))
        if parent_queue:
            recent_builds_parent_queue = Build.objects \
                                             .filter(modified__gte=from_timestamp) \
                                             .filter(builder_display_name=parent_queue)
            processed_patches_parent_queue = set([build.patch for build in recent_builds_parent_queue])
            return len(previously_sent_patches - processed_patches_parent_queue) + 1

        recent_builds = Build.objects \
                            .filter(modified__gte=from_timestamp) \
                            .filter(builder_display_name=queue)
        processed_patches = set([build.patch for build in recent_builds])
        return len(previously_sent_patches - processed_patches) + 1

    def _build_bubbles_for_patch(self, patch):
        show_submit_to_ews = True
        failed_to_apply = False  # TODO: https://bugs.webkit.org/show_bug.cgi?id=194598
        bubbles = []

        if not (patch and patch.sent_to_buildbot):
            return (None, show_submit_to_ews, failed_to_apply)

        for queue in StatusBubble.ALL_QUEUES:
            if not self._should_show_bubble_for_queue(queue):
                continue

            bubble = self._build_bubble(patch, queue)
            if bubble:
                show_submit_to_ews = False
                bubbles.append(bubble)

        return (bubbles, show_submit_to_ews, failed_to_apply)

    @xframe_options_exempt
    def get(self, request, patch_id):
        patch_id = int(patch_id)
        patch = Patch.get_patch(patch_id)
        bubbles, show_submit_to_ews, show_failure_to_apply = self._build_bubbles_for_patch(patch)

        template_values = {
            'bubbles': bubbles,
            'patch_id': patch_id,
            'show_submit_to_ews': show_submit_to_ews,
            'show_failure_to_apply': show_failure_to_apply,
        }
        return render(request, 'statusbubble.html', template_values)
