# Copyright (c) 2019 The Regents of the University of California
# 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 the copyright holders 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 textwrap


class TerminalFormatter:
    def __init__(self, max_width=80):
        # text_width holds the actual width we'll be wrapping to.
        # This takes into account the current terminal size.
        self.__text_width = min(max_width, self.__terminal_size()[0])

    def __terminal_size(self):
        import fcntl, termios, struct

        h, w, hp, wp = struct.unpack(
            "HHHH",
            fcntl.ioctl(
                0, termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0)
            ),
        )
        return w, h

    def __get_paragraphs(self, text, flatten=False):

        """
        This function takes a text and returns a list of constituent
        paragraphs, defining a paragraph as a block of text separated from
        other text by a blank line (or one containing only whitespace). If the
        "flatten" argument is set to true, all line breaks within paragraphs
        will be removed.

        E.g.:

        text = '''Hello, this is
        paragraph number 1.

        This is paragraph number 2.

        And this is
        paragraph number 3.
        '''

        __get_paragraphs(text, False)
        ["Hello, this is\nparagraph number 1", "This is paragraph number 2.",
            "And this is\npagraph number 3."]

        __get_paragraphs(text, True)
        ["Hello, this is paragraph number 1", "This is paragraph number 2.",
            "And this is pagraph number 3."]
        """

        paragraphs = []
        cur_paragraph = []

        for line in text.splitlines():
            stripped = line.strip()
            if not stripped:  # I.e. a blank line.
                paragraphs.append(
                    {False: "\n", True: " "}[flatten].join(cur_paragraph)
                )
                cur_paragraph = []
            else:
                cur_paragraph.append(stripped)

        paragraphs.append(
            {False: "\n", True: " "}[flatten].join(cur_paragraph)
        )

        return paragraphs

    def format_output(self, text, label="", indent=0):
        """
        This function aids in the formatting of outputs. When obtaining
        the list of sim object we desire the output in the following
        format:

        desc: Address to mask loading binaries with, if 0,
              system auto-calculates the mask to be the most
              restrictive, otherwise it obeys a custom mask.

        We must take into account the width of the text, and wrap
        accordingly. We also must display the label.

        Keyword arguments:

        text --- The description text.
        label --- The label of the output (e.g. "desc: ").
        indent --- The white space width before each line.
        """

        if not text.strip():
            return ""

        # The text  may be over multiple lines (as when using triple
        # double quotes). First, we split the text into its constituent
        # paragraphs and remove new line characters from each.
        paragraphs = self.__get_paragraphs(text, True)

        # Wrap and Indent the paragraphs
        wrapper = textwrap.TextWrapper(
            width=max((self.__text_width - indent), 1)
        )
        # The first paragraph is special case due to the inclusion of the label
        formatted_paragraphs = [
            " " * max((indent - len(label)), 0)
            + label
            + wrapper.wrap(paragraphs[0])[0]
        ]
        for paragraph in paragraphs:
            for line in wrapper.wrap(paragraph[1:])[1:]:
                formatted_paragraphs.append(" " * indent + line)
            formatted_paragraphs.append("\n")

        # Remove the last line break
        return "\n".join(formatted_paragraphs[:-1])
