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

from gi.repository import GLib

import os
import pytest
import shutil
from typing import Callable
import unittest
import warnings

from test_note_exporter import MockHtmlGenerator

from iotas.markdown_render_view import MarkdownRenderView
from iotas.note import Note
from iotas.webkit_pdf_exporter import WebKitPdfExporter

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


class Test(unittest.TestCase):

    exporter: WebKitPdfExporter
    generator = MockHtmlGenerator
    success = False

    def test_export(self) -> None:
        # TODO Skipped during CI for segfault
        if "DISPLAY" not in os.environ:
            return pytest.skip("DISPLAY not set")

        out_dir = self.__prepare_output_dir()
        out_path = os.path.join(out_dir, "out.pdf")

        note = Note(new_note=True)
        note.content = "content"
        note.title = "Test Note Title"

        self.__reset()
        self.__call_and_wait(self.exporter.export, note, out_path)
        self.assertTrue(self.success)

        self.assertTrue(os.path.exists(out_path))
        self.assertGreater(os.path.getsize(out_path), 20000)

        # TODO improve validation of content. pdfminer.six below was having an issue building in the
        # flatpak toolchain.
        # from subprocess import run
        # p = run(
        #     [f"pdf2txt.py {out_path}"], shell=True, universal_newlines=True, capture_output=True
        # )
        # if p.returncode != 0:
        #     print(p.stderr)
        # self.assertEqual(p.returncode, 0)
        # self.assertEqual(p.stdout.strip(), self.generator.get_output(note))

        self.__clean_output_dir()

    def __reset(self, tex_support=False) -> None:
        self.generator = MockHtmlGenerator()
        render_view = MarkdownRenderView()
        render_view.setup(self.generator, config_manager=None, track_timing=False)
        self.exporter = WebKitPdfExporter(render_view, keep_webkit_process=False)
        self.exporter.set_callbacks(self.__on_finished, self.__on_failed)

    def __prepare_output_dir(self) -> str:
        out_path = self.__get_output_dir()
        if os.path.exists(out_path):
            shutil.rmtree(out_path)
        os.makedirs(out_path)
        return out_path

    def __clean_output_dir(self) -> None:
        out_path = self.__get_output_dir()
        if os.path.exists(out_path):
            shutil.rmtree(out_path)

    def __get_output_dir(self) -> str:
        file_dir = os.path.dirname(__file__)
        return os.path.join(file_dir, os.pardir, "testing-tmp")

    def __call_and_wait(self, call: Callable, *args) -> None:
        context = GLib.MainContext.default()
        self.success = False
        self.awaiting_signal = True
        call(*args)
        while self.awaiting_signal:
            context.iteration(False)

    def __on_finished(self) -> None:
        self.awaiting_signal = False
        self.success = True

    def __on_failed(self, error) -> None:
        print(f"Failed: {error}")
        self.awaiting_signal = False
