from pathlib import Path
from json import loads
import re

from hotdoc.core.exceptions import HotdocSourceException
from hotdoc.core.extension import Extension
from hotdoc.core.tree import Page
from hotdoc.core.project import Project
from hotdoc.run_hotdoc import Application
from hotdoc.core.formatter import Formatter
from hotdoc.utils.loggable import Logger, warn, info

import typing as T

if T.TYPE_CHECKING:
    import argparse

Logger.register_warning_code('unknown-refman-link', HotdocSourceException, 'refman-links')

class RefmanLinksExtension(Extension):
    extension_name = 'refman-links'
    argument_prefix = 'refman'

    def __init__(self, app: Application, project: Project):
        self.project: Project
        super().__init__(app, project)
        self._data_file: T.Optional[Path] = None
        self._data: T.Dict[str, str] = {}

    @staticmethod
    def add_arguments(parser: 'argparse.ArgumentParser'):
        group = parser.add_argument_group(
            'Refman links',
            'Custom Meson extension',
        )

        # Add Arguments with `group.add_argument(...)`
        group.add_argument(
            f'--refman-data-file',
            help="JSON file with the mappings to replace",
            default=None,
        )

    def parse_config(self, config: T.Dict[str, T.Any]) -> None:
        super().parse_config(config)
        self._data_file = config.get('refman_data_file')

    def _formatting_page_cb(self, formatter: Formatter, page: Page) -> None:
        ''' Replace Meson refman tags

        Links of the form [[function]] are automatically replaced
        with valid links to the correct URL. To reference objects / types use the
        [[@object]] syntax.
        '''
        link_regex = re.compile(r'\[\[#?@?([ \n\t]*[a-zA-Z0-9_]+[ \n\t]*\.)*[ \n\t]*[a-zA-Z0-9_]+[ \n\t]*\]\]', re.MULTILINE)
        for m in link_regex.finditer(page.formatted_contents):
            i = m.group()
            obj_id: str = i[2:-2]
            obj_id = re.sub(r'[ \n\t]', '', obj_id)  # Remove whitespaces

            # Marked as inside a code block?
            in_code_block = False
            if obj_id.startswith('#'):
                in_code_block = True
                obj_id = obj_id[1:]

            if obj_id not in self._data:
                warn('unknown-refman-link', f'{Path(page.name).name}: Unknown Meson refman link: "{obj_id}"')
                continue

            # Just replaces [[!file.id]] paths with the page file (no fancy HTML)
            if obj_id.startswith('!'):
                page.formatted_contents = page.formatted_contents.replace(i, self._data[obj_id])
                continue

            # Fancy links for functions and methods
            text = obj_id
            if text.startswith('@'):
                text = text[1:]
            else:
                text = text + '()'
            if not in_code_block:
                text = f'<code>{text}</code>'
            link = f'<a href="{self._data[obj_id]}"><ins>{text}</ins></a>'
            page.formatted_contents = page.formatted_contents.replace(i, link)

    def setup(self) -> None:
        super().setup()

        if not self._data_file:
            info('Meson refman extension DISABLED')
            return

        raw = Path(self._data_file).read_text(encoding='utf-8')
        self._data = loads(raw)

        # Register formater
        for ext in self.project.extensions.values():
            ext = T.cast(Extension, ext)
            ext.formatter.formatting_page_signal.connect(self._formatting_page_cb)
        info('Meson refman extension LOADED')

    @staticmethod
    def get_dependencies() -> T.List[T.Type[Extension]]:
        return []  # In case this extension has dependencies on other extensions

def get_extension_classes() -> T.List[T.Type[Extension]]:
    return [RefmanLinksExtension]
