# Copyright (c) 2010 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
import optparse
import sys
import urllib

from webkitpy.common.prettypatch import PrettyPatch
from webkitpy.common.system.executive import ScriptError
from webkitpy.tool.commands.command import Command


_log = logging.getLogger(__name__)


class PrettyDiff(Command):
    name = 'pretty-diff'
    help_text = 'Shows the pretty diff in the default browser'
    show_in_main_help = True

    def __init__(self):
        options = [
            optparse.make_option('-g', '--git-commit', action='store', dest='git_commit',
                                 help=('Operate on a local commit. If a range, the commits are squashed into one. <ref>.... '
                                       'includes the working copy changes. UPSTREAM can be used for the upstream/tracking branch.'))
        ]
        super(PrettyDiff, self).__init__(options)
        self._tool = None

    def execute(self, options, args, tool):
        self._tool = tool
        pretty_diff_file = self._show_pretty_diff(options)
        if pretty_diff_file:
            diff_correct = tool.user.confirm('Was that diff correct?')
            pretty_diff_file.close()
            if not diff_correct:
                sys.exit(1)

    def _show_pretty_diff(self, options):
        if not self._tool.user.can_open_url():
            return None
        try:
            pretty_patch = PrettyPatch(self._tool.executive)
            patch = self._diff(options)
            pretty_diff_file = pretty_patch.pretty_diff_file(patch)
            self._open_pretty_diff(pretty_diff_file.name)
            # We return the pretty_diff_file here because we need to keep the
            # file alive until the user has had a chance to confirm the diff.
            return pretty_diff_file
        except ScriptError as error:
            _log.warning('PrettyPatch failed.  :(')
            _log.error(error.message_with_output())
            self._exit(error.exit_code or 2)
        except OSError:
            _log.warning('PrettyPatch unavailable.')

    def _diff(self, options):
        changed_files = self._tool.git().changed_files(options.git_commit)
        return self._tool.git().create_patch(options.git_commit,
                                             changed_files=changed_files)

    def _open_pretty_diff(self, file_path):
        if self._tool.platform.is_cygwin():
            assert file_path.endswith('.html')
            self._tool.executive.run_command(['cygstart', file_path])
            return
        url = 'file://%s' % urllib.quote(file_path)
        self._tool.user.open_url(url)
