"""An IDLE extension to avoid having very long texts printed in the shell.

A common problem in IDLE's interactive shell is printing of large amounts of
text into the shell. This makes looking at the previous history difficult.
Worse, this can cause IDLE to become very slow, even to the point of being
completely unusable.

This extension will automatically replace long texts with a small button.
Double-clicking this button will remove it and insert the original text instead.
Middle-clicking will copy the text to the clipboard. Right-clicking will open
the text in a separate viewing window.

Additionally, any output can be manually "squeezed" by the user. This includes
output written to the standard error stream ("stderr"), such as exception
messages and their tracebacks.
"""
import re

import tkinter as tk
import tkinter.messagebox as tkMessageBox

from idlelib.config import idleConf
from idlelib.textview import view_text
from idlelib.tooltip import Hovertip
from idlelib import macosx


def count_lines_with_wrapping(s, linewidth=80):
    """Count the number of lines in a given string.

    Lines are counted as if the string was wrapped so that lines are never over
    linewidth characters long.

    Tabs are considered tabwidth characters long.
    """
    tabwidth = 8  # Currently always true in Shell.
    pos = 0
    linecount = 1
    current_column = 0

    for m in re.finditer(r"[\t\n]", s):
        # Process the normal chars up to tab or newline.
        numchars = m.start() - pos
        pos += numchars
        current_column += numchars

        # Deal with tab or newline.
        if s[pos] == '\n':
            # Avoid the `current_column == 0` edge-case, and while we're
            # at it, don't bother adding 0.
            if current_column > linewidth:
                # If the current column was exactly linewidth, divmod
                # would give (1,0), even though a new line hadn't yet
                # been started. The same is true if length is any exact
                # multiple of linewidth. Therefore, subtract 1 before
                # dividing a non-empty line.
                linecount += (current_column - 1) // linewidth
            linecount += 1
            current_column = 0
        else:
            assert s[pos] == '\t'
            current_column += tabwidth - (current_column % tabwidth)

            # If a tab passes the end of the line, consider the entire
            # tab as being on the next line.
            if current_column > linewidth:
                linecount += 1
                current_column = tabwidth

        pos += 1 # After the tab or newline.

    # Process remaining chars (no more tabs or newlines).
    current_column += len(s) - pos
    # Avoid divmod(-1, linewidth).
    if current_column > 0:
        linecount += (current_column - 1) // linewidth
    else:
        # Text ended with newline; don't count an extra line after it.
        linecount -= 1

    return linecount


class ExpandingButton(tk.Button):
    """Class for the "squeezed" text buttons used by Squeezer

    These buttons are displayed inside a Tk Text widget in place of text. A
    user can then use the button to replace it with the original text, copy
    the original text to the clipboard or view the original text in a separate
    window.

    Each button is tied to a Squeezer instance, and it knows to update the
    Squeezer instance when it is expanded (and therefore removed).
    """
    def __init__(self, s, tags, numoflines, squeezer):
        self.s = s
        self.tags = tags
        self.numoflines = numoflines
        self.squeezer = squeezer
        self.editwin = editwin = squeezer.editwin
        self.text = text = editwin.text
        # The base Text widget is needed to change text before iomark.
        self.base_text = editwin.per.bottom

        line_plurality = "lines" if numoflines != 1 else "line"
        button_text = f"Squeezed text ({numoflines} {line_plurality})."
        tk.Button.__init__(self, text, text=button_text,
                           background="#FFFFC0", activebackground="#FFFFE0")

        button_tooltip_text = (
            "Double-click to expand, right-click for more options."
        )
        Hovertip(self, button_tooltip_text, hover_delay=80)

        self.bind("<Double-Button-1>", self.expand)
        if macosx.isAquaTk():
            # AquaTk defines <2> as the right button, not <3>.
            self.bind("<Button-2>", self.context_menu_event)
        else:
            self.bind("<Button-3>", self.context_menu_event)
        self.selection_handle(  # X windows only.
            lambda offset, length: s[int(offset):int(offset) + int(length)])

        self.is_dangerous = None
        self.after_idle(self.set_is_dangerous)

    def set_is_dangerous(self):
        dangerous_line_len = 50 * self.text.winfo_width()
        self.is_dangerous = (
            self.numoflines > 1000 or
            len(self.s) > 50000 or
            any(
                len(line_match.group(0)) >= dangerous_line_len
                for line_match in re.finditer(r'[^\n]+', self.s)
            )
        )

    def expand(self, event=None):
        """expand event handler

        This inserts the original text in place of the button in the Text
        widget, removes the button and updates the Squeezer instance.

        If the original text is dangerously long, i.e. expanding it could
        cause a performance degradation, ask the user for confirmation.
        """
        if self.is_dangerous is None:
            self.set_is_dangerous()
        if self.is_dangerous:
            confirm = tkMessageBox.askokcancel(
                title="Expand huge output?",
                message="\n\n".join([
                    "The squeezed output is very long: %d lines, %d chars.",
                    "Expanding it could make IDLE slow or unresponsive.",
                    "It is recommended to view or copy the output instead.",
                    "Really expand?"
                ]) % (self.numoflines, len(self.s)),
                default=tkMessageBox.CANCEL,
                parent=self.text)
            if not confirm:
                return "break"

        self.base_text.insert(self.text.index(self), self.s, self.tags)
        self.base_text.delete(self)
        self.squeezer.expandingbuttons.remove(self)

    def copy(self, event=None):
        """copy event handler

        Copy the original text to the clipboard.
        """
        self.clipboard_clear()
        self.clipboard_append(self.s)

    def view(self, event=None):
        """view event handler

        View the original text in a separate text viewer window.
        """
        view_text(self.text, "Squeezed Output Viewer", self.s,
                  modal=False, wrap='none')

    rmenu_specs = (
        # Item structure: (label, method_name).
        ('copy', 'copy'),
        ('view', 'view'),
    )

    def context_menu_event(self, event):
        self.text.mark_set("insert", "@%d,%d" % (event.x, event.y))
        rmenu = tk.Menu(self.text, tearoff=0)
        for label, method_name in self.rmenu_specs:
            rmenu.add_command(label=label, command=getattr(self, method_name))
        rmenu.tk_popup(event.x_root, event.y_root)
        return "break"


class Squeezer:
    """Replace long outputs in the shell with a simple button.

    This avoids IDLE's shell slowing down considerably, and even becoming
    completely unresponsive, when very long outputs are written.
    """
    @classmethod
    def reload(cls):
        """Load class variables from config."""
        cls.auto_squeeze_min_lines = idleConf.GetOption(
            "main", "PyShell", "auto-squeeze-min-lines",
            type="int", default=50,
        )

    def __init__(self, editwin):
        """Initialize settings for Squeezer.

        editwin is the shell's Editor window.
        self.text is the editor window text widget.
        self.base_test is the actual editor window Tk text widget, rather than
            EditorWindow's wrapper.
        self.expandingbuttons is the list of all buttons representing
            "squeezed" output.
        """
        self.editwin = editwin
        self.text = text = editwin.text

        # Get the base Text widget of the PyShell object, used to change
        # text before the iomark. PyShell deliberately disables changing
        # text before the iomark via its 'text' attribute, which is
        # actually a wrapper for the actual Text widget. Squeezer,
        # however, needs to make such changes.
        self.base_text = editwin.per.bottom

        # Twice the text widget's border width and internal padding;
        # pre-calculated here for the get_line_width() method.
        self.window_width_delta = 2 * (
            int(text.cget('border')) +
            int(text.cget('padx'))
        )

        self.expandingbuttons = []

        # Replace the PyShell instance's write method with a wrapper,
        # which inserts an ExpandingButton instead of a long text.
        def mywrite(s, tags=(), write=editwin.write):
            # Only auto-squeeze text which has just the "stdout" tag.
            if tags != "stdout":
                return write(s, tags)

            # Only auto-squeeze text with at least the minimum
            # configured number of lines.
            auto_squeeze_min_lines = self.auto_squeeze_min_lines
            # First, a very quick check to skip very short texts.
            if len(s) < auto_squeeze_min_lines:
                return write(s, tags)
            # Now the full line-count check.
            numoflines = self.count_lines(s)
            if numoflines < auto_squeeze_min_lines:
                return write(s, tags)

            # Create an ExpandingButton instance.
            expandingbutton = ExpandingButton(s, tags, numoflines, self)

            # Insert the ExpandingButton into the Text widget.
            text.mark_gravity("iomark", tk.RIGHT)
            text.window_create("iomark", window=expandingbutton,
                               padx=3, pady=5)
            text.see("iomark")
            text.update()
            text.mark_gravity("iomark", tk.LEFT)

            # Add the ExpandingButton to the Squeezer's list.
            self.expandingbuttons.append(expandingbutton)

        editwin.write = mywrite

    def count_lines(self, s):
        """Count the number of lines in a given text.

        Before calculation, the tab width and line length of the text are
        fetched, so that up-to-date values are used.

        Lines are counted as if the string was wrapped so that lines are never
        over linewidth characters long.

        Tabs are considered tabwidth characters long.
        """
        return count_lines_with_wrapping(s, self.editwin.width)

    def squeeze_current_text_event(self, event):
        """squeeze-current-text event handler

        Squeeze the block of text inside which contains the "insert" cursor.

        If the insert cursor is not in a squeezable block of text, give the
        user a small warning and do nothing.
        """
        # Set tag_name to the first valid tag found on the "insert" cursor.
        tag_names = self.text.tag_names(tk.INSERT)
        for tag_name in ("stdout", "stderr"):
            if tag_name in tag_names:
                break
        else:
            # The insert cursor doesn't have a "stdout" or "stderr" tag.
            self.text.bell()
            return "break"

        # Find the range to squeeze.
        start, end = self.text.tag_prevrange(tag_name, tk.INSERT + "+1c")
        s = self.text.get(start, end)

        # If the last char is a newline, remove it from the range.
        if len(s) > 0 and s[-1] == '\n':
            end = self.text.index("%s-1c" % end)
            s = s[:-1]

        # Delete the text.
        self.base_text.delete(start, end)

        # Prepare an ExpandingButton.
        numoflines = self.count_lines(s)
        expandingbutton = ExpandingButton(s, tag_name, numoflines, self)

        # insert the ExpandingButton to the Text
        self.text.window_create(start, window=expandingbutton,
                                padx=3, pady=5)

        # Insert the ExpandingButton to the list of ExpandingButtons,
        # while keeping the list ordered according to the position of
        # the buttons in the Text widget.
        i = len(self.expandingbuttons)
        while i > 0 and self.text.compare(self.expandingbuttons[i-1],
                                          ">", expandingbutton):
            i -= 1
        self.expandingbuttons.insert(i, expandingbutton)

        return "break"


Squeezer.reload()


if __name__ == "__main__":
    from unittest import main
    main('idlelib.idle_test.test_squeezer', verbosity=2, exit=False)

    # Add htest.
