from __future__ import annotations

from oarepo_cli.cli.site.utils import SiteWizardStepMixin
from oarepo_cli.ui.wizard import WizardStep


class FixupSiteCodeStep(SiteWizardStepMixin, WizardStep):
    def __init__(self, **kwargs):
        super().__init__(
            heading="""
Current invenio sources have some hard-coded values in subsequent checks.
In this step I'll patch them up to use the current invenio config.
""",
            **kwargs,
        )

    def get_service_health_file(self):
        invenio_cli_venv = (
            self.data.project_dir / self.data.get("config.invenio_cli")
        ).parent.parent
        for candidate in invenio_cli_venv.rglob("services_health.py"):
            if (
                candidate.parent.name == "commands"
                and candidate.parent.parent.name == "invenio_cli"
            ):
                return candidate
        raise Exception(
            "Can not find services_health.py - it seems that Invenio has changed its source files structure. Please report this issue to du-suppport@cestnet.cz"
        )

    def after_run(self):
        health_file = self.get_service_health_file()
        contents = health_file.read_text()
        contents = contents.replace(
            '"localhost:9200/_cluster/health?wait_for_status=yellow"',
            "oarepo_elasticsearch_patch()",
        )
        contents = (
            contents
            + """
def oarepo_elasticsearch_patch():
    from pathlib import Path
    import re
    cwd = Path.cwd()
    invenio_cfg = cwd / 'invenio.cfg'
    if not invenio_cfg.exists():
        raise Exception(f'Please run the check script from within the site directory. Current directory is {cwd}')
    loading = False
    lines = []
    for l in invenio_cfg.read_text().split('\\n'):
        if loading:
            lines.append(l)
            if not l.startswith(' '):
                break
        if l.startswith('SEARCH_HOSTS'):
            loading = True
            lines.append(l)
    g = {}
    lines[0] = re.sub('SEARCH_HOSTS\\s*=', '', lines[0])
    # eval is nasty, but here it should be ok - the invenio.cfg was generated by us
    ret = eval('\\n'.join(lines), g, g)
    search_decl = ret[0]
    return f"{search_decl['host']}:{search_decl['port']}/_cluster/health?wait_for_status=yellow"        """
        )
        health_file.write_text(contents)

    def should_run(self):
        health_file = self.get_service_health_file()
        contents = health_file.read_text()
        return "oarepo_elasticsearch_patch" not in contents
