"""
https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecDataDir
"""
import asyncio
import os
import logging

from defence360agent.subsys.panels import hosting_panel
from defence360agent.utils import retry_on
from defence360agent.subsys import web_server

logger = logging.getLogger(__name__)


def get_sec_data_dir(modsec_config_path):
    param_name = "SecDataDir"
    try:
        with open(modsec_config_path) as f:
            for line in f:
                parts = line.split(maxsplit=1)
                if len(parts) == 2 and parts[0].lower() == param_name.lower():
                    return parts[1].strip().strip("'\"")
    except OSError as e:
        logger.warning(
            "Cannot read modsec config %s: %s", modsec_config_path, e
        )
        return None
    logger.warning(
        "%s not found in modsec config %s; ModSecurity persistent"
        " collections directory will not be created by the agent",
        param_name,
        modsec_config_path,
    )
    return None


async def create_modsec_cache_directory():
    """
    Create modsec cache directory because sometimes a directory may not exist
    :return:
    """
    try:
        modsec_config_path = (
            hosting_panel.HostingPanel().get_modsec_config_path()
        )
    except NotImplementedError as e:
        logger.debug(
            "get_modsec_config_path is not implemented for current "
            "hosting_panel %s",
            e,
        )
        return
    if not modsec_config_path or not os.path.exists(modsec_config_path):
        return

    sec_data_dir = get_sec_data_dir(modsec_config_path)
    if sec_data_dir and not os.path.exists(sec_data_dir):
        try:
            os.makedirs(sec_data_dir)

            # The directory to which the directive points must be
            # writable by the web server user.

            async def pause(*_):
                await asyncio.sleep(60)  # wait a minute between attempts

            @retry_on(web_server.NotRunningError, on_error=pause, max_tries=5)
            async def coro():
                web_server.chown(sec_data_dir)

            await coro()

            logger.info("Successfully created sec_data_dir %s", sec_data_dir)
            await web_server.graceful_restart()
        except OSError as e:
            logger.error("Error when creating sec_data_dir %s", e)
