# SPDX-FileCopyrightText: 2022 Chris Heywood
#
# SPDX-License-Identifier: GPL-3.0-or-later

import os
import unittest
import warnings

from iotas.html_generator_configuration import HtmlGeneratorConfiguration

from iotas.markdown_helpers import parse_to_tokens
from iotas.note import Note
from iotas.template_html_generator import TemplateHtmlGenerator, TemplateDetails

warnings.filterwarnings("ignore", "version")


class _TestHtmlGeneratorConfig(HtmlGeneratorConfiguration):

    tex_support = False

    @property
    def markdown_tex_support(self) -> bool:
        """Get whether markdown TeX rendering is supported.

        :return: Markdown TeX supported
        :rtype: bool
        """
        return self.tex_support

    @property
    def line_length(self) -> int:
        """Get line length.

        :return: Size in pixels
        :rtype: int
        """
        return 800

    @property
    def markdown_use_monospace_font(self) -> bool:
        """Get whether to use a monospace font for the markdown render.

        :return: Using monospace font
        :rtype: bool
        """
        return False

    @property
    def use_monospace_font(self) -> bool:
        """Get whether to use a monospace font.

        :return: Using monospace font
        :rtype: bool
        """
        return True

    @property
    def font_size(self) -> int:
        """Get font size.

        :return: Size
        :rtype: int
        """
        return 14

    @property
    def high_contrast(self) -> bool:
        """Get whether high contrast output should be used for screen rendering.

        :return: Whether visible
        :rtype: bool
        """
        return False

    @property
    def markdown_render_monospace_font_ratio(self) -> float:
        """Get the adjustment in size from proportional to fixed width font.

        :return: Ratio
        :rtype: float
        """
        return 1.0

    @property
    def editor_header_bar_visible_for_window_state(self) -> bool:
        """Get whether the header bar is configured visible for the window maximised state."

        :return: Whether visible
        :rtype: bool
        """
        return False


class Test(unittest.TestCase):

    def test_generate(self) -> None:
        note = Note(new_note=True)
        note.content = "content"
        note.id = 1
        note.title = "Test Note Title"

        generator = self.__reset()
        parser, tokens = parse_to_tokens(note, exporting=False, tex_support=False)
        html = generator.generate(
            note,
            tokens,
            parser.renderer.render,
            parser.options,
            searching=False,
            export_format=None,
        )
        self.assertTrue(note.content in html)
        self.assertTrue(note.title in html)
        self.assertFalse("katex" in html)
        self.assertFalse("<style>" in html)
        self.assertFalse("scrollTop = " in html)
        self.assertTrue("/mock/data/path" in html)

        generator = self.__reset(tex_support=True)
        parser, tokens = parse_to_tokens(note, exporting=False, tex_support=True)
        html = generator.generate(
            note,
            tokens,
            parser.renderer.render,
            parser.options,
            searching=False,
            export_format=None,
        )
        self.assertTrue("katex" in html)

        generator = self.__reset()
        parser, tokens = parse_to_tokens(note, exporting=False, tex_support=False)
        html = generator.generate(
            note,
            tokens,
            parser.renderer.render,
            parser.options,
            searching=False,
            export_format=None,
            scroll_position=100.0,
        )
        self.assertTrue("scrollTop = 100.0" in html)

        note.content = "![title](https://imageurl.com/image.png)"
        generator = self.__reset()
        parser, tokens = parse_to_tokens(note, exporting=False, tex_support=False)
        html = generator.generate(
            note,
            tokens,
            parser.renderer.render,
            parser.options,
            searching=False,
            export_format=None,
        )
        self.assertTrue('loading="lazy"' in html)

        note.content = "![](image.png)"
        generator = self.__reset()
        parser, tokens = parse_to_tokens(note, exporting=False, tex_support=False)
        html = generator.generate(
            note,
            tokens,
            parser.renderer.render,
            parser.options,
            searching=False,
            export_format=None,
        )
        self.assertTrue('src="image.png"' in html)

        generator = self.__reset()
        parser, tokens = parse_to_tokens(note, exporting=True, tex_support=False)
        html = generator.generate(
            note,
            tokens,
            parser.renderer.render,
            parser.options,
            searching=False,
            export_format="html",
        )
        self.assertTrue('src="attachments/image.png"' in html)

        generator = self.__reset()
        parser, tokens = parse_to_tokens(note, exporting=True, tex_support=False)
        html = generator.generate(
            note,
            tokens,
            parser.renderer.render,
            parser.options,
            searching=False,
            export_format="html",
        )
        self.assertFalse("scrollTop = " in html)
        self.assertTrue("font-size: 14pt" in html)
        self.assertTrue("max-width: 800px" in html)
        self.assertTrue("padding-top: 47px" in html)
        self.assertFalse("::selection {" in html)
        self.assertFalse("/mock/data/path" in html)
        self.assertFalse('loading="lazy"' in html)

    def test_generate_user_stylesheet(self) -> None:
        generator = self.__reset()
        css = generator.generate_user_stylesheet(searching=False, height=500)
        self.assertTrue("font-size: 14pt" in css)
        self.assertTrue("max-width: 800px" in css)
        self.assertTrue("padding-top: 47px" in css)
        self.assertTrue("padding-bottom: 200px" in css)
        self.assertFalse("::selection {" in css)

        css = generator.generate_user_stylesheet(searching=True, height=500)
        self.assertTrue("::selection {" in css)

    def test_update_font_family(self) -> None:
        generator = self.__reset()
        generator.update_font_family("unique")
        css = generator.generate_user_stylesheet(searching=False, height=500)
        self.assertTrue("font-family: unique" in css)

    def __reset(self, tex_support=False) -> TemplateHtmlGenerator:
        config = _TestHtmlGeneratorConfig()
        config.tex_support = tex_support
        data_path = "/mock/data/path"
        header_bar_height = 47
        return TemplateHtmlGenerator(config, data_path, header_bar_height, self.__template_loader)

    def __template_loader(self) -> TemplateDetails:
        file_dir = os.path.dirname(__file__)
        templates_path = os.path.join(file_dir, os.pardir, "data", "render-template")
        with open(os.path.join(templates_path, "template.html"), "r") as f:
            html = f.read()
        with open(os.path.join(templates_path, "binding.js"), "r") as f:
            js = f.read()
        with open(os.path.join(templates_path, "configurable.css"), "r") as f:
            css = f.read()
        with open(os.path.join(templates_path, "searching.css"), "r") as f:
            search_css = f.read()
        return TemplateDetails(html, js, css, search_css)
