from pathlib import Path
from json import loads
import os
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.core.symbols import *
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.
        '''
        for key, value in self._data.items():
            path = os.path.relpath(value, self.app.config.get_invoke_dir()).split('#')[0]
            if path == page.link.ref:
                if key.startswith('@'):
                    res = self.create_symbol(
                        ClassSymbol,
                        display_name=key[1:],
                        filename=path,
                        unique_name=key)
                    res.link = Link(value, res.display_name, res.unique_name)
                elif '.' in key:
                    res = self.create_symbol(
                        MethodSymbol,
                        parameters=[],
                        display_name=key.split('.')[-1],
                        parent_name=f'@{key.split(".")[-2]}',
                        filename=path,
                        unique_name=key)
                    res.link = Link(value, key, res.unique_name)
                else:
                    res = self.create_symbol(
                        FunctionSymbol,
                        parameters=[],
                        display_name=key,
                        filename=path,
                        unique_name=key)
                    res.link = Link(value, res.display_name, res.unique_name)
                page.symbols.append(res)

        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(1)
            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:]
            elif in_code_block:
                if m.group(3) != '(':
                    text = text + '()'
            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, 1)

    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 formatter
        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')

    def create_symbol(self, *args, **kwargs):
        kwargs['language'] = 'meson'
        return super(RefmanLinksExtension, self).create_symbol(*args, **kwargs)

    @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]
