# SPDX-FileCopyrightText: © 2023 Christian BUHTZ <c.buhtz@posteo.jp>
#
# SPDX-License-Identifier: GPL-3.0-only
#
# This file is part of the program "Hyperorg" which is released under GNU
# General Public License v3 (GPLv3).
# See folder LICENSES or go to <https://www.gnu.org/licenses/#GPL>.
"""Helper functions and data for unit tests.

Some functions helping with repetitive task while running unittests.
"""
import random
import string
import re


def rand_string(max_length: int = 25, min_length: int = 1):
    """Create a string with random uppercase characters and digits. Default
    length is 25.

    Args:
        max_length (int): Max length of the string (default: 25).
        min_length (int): Min string length (default: 1)

    Returns:
        (string): The created random string.
    """
    return ''.join(random.choice(string.ascii_uppercase + string.digits) for _
                   in range(random.randint(min_length, max_length)))


class MockWriter:
    """Collect all written data.

    https://stackoverflow.com/a/70868549/4865723
    """

    def __init__(self):
        self.contents = ''

    def write(self, data):
        """Add data to the content."""
        self.contents += data

    def pop_contents(self) -> str:
        """Return content and remove it from the object."""
        to_pop = self.contents
        self.contents = ''
        return to_pop


def unify_html(html, join_string: str = ' ') -> str:
    """Createas a unified and comparable HTML string.

    Args:
        html (str): The HTML string to unify.

    Returns:
        (str): The unified string

    Beside other modifications mainly newlines and indentions are removed.
    """
    unified_html = f'{join_string}'.join(
        [line.strip() for line in html.split('\n')])

    # remove trailing whitespace
    unified_html = unified_html.strip()

    unified_html = unified_html.replace(' &nbsp;', '&nbsp;')
    unified_html = unified_html.replace('&nbsp; ', '&nbsp;')

    # fix line breaks and (multiple) blanks between tags
    # e.g. "</body>     </html>"
    unified_html = re.sub(r'>\s+<', '><', unified_html)

    return unified_html


def extract_html_hyperorg_content(html, tags='section'):
    """Extract html part that is related to the 'body' of the content
    instance.

    By default it is everything between the ``section``-tag.
    """
    if isinstance(tags, tuple):
        tag_open, tag_close = tags
    else:
        tag_open = tags
        tag_close = tags

    # The "single line" mode modifier '(?s)' does take care that this
    # regex work on multilines two.
    # Credits: https://stackoverflow.com/a/21766670/4865723
    # Credits. https://stackoverflow.com/a/75097992/4865723
    pattern = fr'(?s)<{tag_open}(?: [^>]+)?>(.+?)</{tag_close}>'

    return re.findall(
        # r'<div id="hyperorg-content">(.+?)<hr /><\/div>',
        pattern,
        html,
        re.M | re.DOTALL)[0].strip()
