# Copyright (c) 2012 Google 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:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * 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.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
# OWNER OR 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.

import logging

from webkitpy.tool.bot.irc_command import IRCCommand
from webkitpy.tool.bot.irc_command import Help
from webkitpy.tool.bot.irc_command import Hi
from webkitpy.tool.bot.irc_command import Restart
from webkitpy.tool.bot.ircbot import IRCBot
from webkitpy.tool.bot.patchanalysistask import PatchAnalysisTask, PatchAnalysisTaskDelegate, UnableToApplyPatch
from webkitpy.tool.bot.sheriff import Sheriff
from webkitpy.tool.commands.queues import AbstractQueue
from webkitpy.tool.commands.stepsequence import StepSequenceErrorHandler

_log = logging.getLogger(__name__)


class PerfalizerTask(PatchAnalysisTask):
    def __init__(self, tool, patch, logger):
        PatchAnalysisTask.__init__(self, self, patch)
        self._port = tool.port_factory.get()
        self._tool = tool
        self._logger = logger

    def _copy_build_product_without_patch(self):
        filesystem = self._tool.filesystem
        configuration = filesystem.basename(self._port._build_path())
        self._build_directory = filesystem.dirname(self._port._build_path())
        self._build_directory_without_patch = self._build_directory + 'WithoutPatch'

        try:
            filesystem.rmtree(self._build_directory_without_patch)
            filesystem.copytree(filesystem.join(self._build_directory, configuration),
                filesystem.join(self._build_directory_without_patch, configuration))
            return True
        except:
            return False

    def validate(self):
        return True

    def run(self):
        if not self._patch.committer() and not self._patch.attacher().can_commit:
            self._logger('The patch %d is not authorized by a commmitter' % self._patch.id())
            return False

        self._logger('Preparing to run performance tests for the attachment %d...' % self._patch.id())
        if not self._clean() or not self._update():
            return False

        head_revision = self._tool.scm().head_svn_revision()

        self._logger('Building WebKit at r%s without the patch' % head_revision)
        if not self._build_without_patch():
            return False

        if not self._port.check_build():
            self._logger('Failed to build DumpRenderTree.')
            return False

        if not self._copy_build_product_without_patch():
            self._logger('Failed to copy the build product from %s to %s' % (self._build_directory, self._build_directory_without_patch))
            return False

        self._logger('Building WebKit at r%s with the patch' % head_revision)
        if not self._apply() or not self._build():
            return False

        if not self._port.check_build():
            self._logger('Failed to build DumpRenderTree.')
            return False

        filesystem = self._tool.filesystem
        if filesystem.exists(self._json_path()):
            filesystem.remove(self._json_path())

        self._logger("Running performance tests...")
        if self._run_perf_test(self._build_directory_without_patch, 'without %d' % self._patch.id()) < 0:
            self._logger('Failed to run performance tests without the patch.')
            return False

        if self._run_perf_test(self._build_directory, 'with %d' % self._patch.id()) < 0:
            self._logger('Failed to run performance tests with the patch.')
            return False

        if not filesystem.exists(self._results_page_path()):
            self._logger('Failed to generate the results page.')
            return False

        results_page = filesystem.read_text_file(self._results_page_path())
        self._tool.bugs.add_attachment_to_bug(self._patch.bug_id(), results_page,
            description="Performance tests results for %d" % self._patch.id(), mimetype='text/html')

        self._logger("Uploaded the results on the bug %d" % self._patch.bug_id())
        return True

    def parent_command(self):
        return "perfalizer"

    def run_webkit_patch(self, args):
        webkit_patch_args = [self._tool.path()]
        webkit_patch_args.extend(args)
        return self._tool.executive.run_and_throw_if_fail(webkit_patch_args, cwd=self._tool.scm().checkout_root)

    def _json_path(self):
        return self._tool.filesystem.join(self._build_directory, 'PerformanceTestResults.json')

    def _results_page_path(self):
        return self._tool.filesystem.join(self._build_directory, 'PerformanceTestResults.html')

    def _run_perf_test(self, build_path, description):
        filesystem = self._tool.filesystem
        script_path = filesystem.join(filesystem.dirname(self._tool.path()), 'run-perf-tests')
        perf_test_runner_args = [script_path, '--no-build', '--no-show-results', '--build-directory', build_path,
            '--output-json-path', self._json_path(), '--description', description]
        return self._tool.executive.run_and_throw_if_fail(perf_test_runner_args, cwd=self._tool.scm().checkout_root)

    def run_command(self, command):
        self.run_webkit_patch(command)

    def command_passed(self, message, patch):
        pass

    def command_failed(self, message, script_error, patch):
        self._logger(message)

    def refetch_patch(self, patch):
        return self._tool.bugs.fetch_attachment(patch.id())

    def build_style(self):
        return "release"


class PerfTest(IRCCommand):
    def execute(self, nick, args, tool, sheriff):
        if not args:
            tool.irc().post(nick + ": Please specify an attachment/patch id")
            return

        patch_id = args[0]
        patch = tool.bugs.fetch_attachment(patch_id)
        if not patch:
            tool.irc().post(nick + ": Could not fetch the patch")
            return

        task = PerfalizerTask(tool, patch, lambda message: tool.irc().post('%s: %s' % (nick, message)))
        task.run()


class Perfalizer(AbstractQueue, StepSequenceErrorHandler):
    name = "perfalizer"
    watchers = AbstractQueue.watchers + ["rniwa@webkit.org"]

    _commands = {
        "help": Help,
        "hi": Hi,
        "restart": Restart,
        "test": PerfTest,
    }

    # AbstractQueue methods

    def begin_work_queue(self):
        AbstractQueue.begin_work_queue(self)
        self._sheriff = Sheriff(self._tool, self)
        self._irc_bot = IRCBot("perfalizer", self._tool, self._sheriff, self._commands)
        self._tool.ensure_irc_connected(self._irc_bot.irc_delegate())

    def work_item_log_path(self, failure_map):
        return None

    def _is_old_failure(self, revision):
        return self._tool.status_server.svn_revision(revision)

    def next_work_item(self):
        self._irc_bot.process_pending_messages()
        return

    def process_work_item(self, failure_map):
        return True

    def handle_unexpected_error(self, failure_map, message):
        _log.error(message)

    # StepSequenceErrorHandler methods

    @classmethod
    def handle_script_error(cls, tool, state, script_error):
        # Ideally we would post some information to IRC about what went wrong
        # here, but we don't have the IRC password in the child process.
        pass
