"""
Silique (https://www.silique.fr)
Copyright (C) 2024-2026

This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

from pathlib import Path
from rougail.utils import load_modules

from .i18n import _


OUTPUTS = None


def get_outputs() -> None:
    """Load all outputs"""
    module_name = f"rougail.output_display.output"
    outputs = {}
    names = []
    for path in (Path(__file__).parent / "output").iterdir():
        name = path.name
        if not name.endswith(".py") or name.endswith("__.py"):
            continue
        module = load_modules(module_name + "." + name[:-3], str(path))
        if "OutputFamily" not in dir(module):
            continue
        obj_class = module.OutputFamily
        level = obj_class.level
        if level in outputs:
            raise ImportError(
                _(
                    'duplicated level in rougail-output-display for output "{0}": {1} and {2}'
                ).format(level, obj_class.name, outputs[level].name)
            )
        if obj_class.name in names:
            raise ImportError(
                _('duplicated name "{0}" in rougail-output-display').format(
                    obj_class.name
                )
            )
        names.append(obj_class.name)
        outputs[level] = obj_class
    return {outputs[level].name: outputs[level] for level in sorted(outputs)}


class OutPuts:  # pylint: disable=R0903
    """Transformations applied on a object instance"""

    def __init__(
        self,
    ) -> None:
        global OUTPUTS
        if OUTPUTS is None:
            OUTPUTS = get_outputs()

    def get(self) -> dict:
        """Get all outputs"""
        return OUTPUTS


def get_rougail_config(
    *,
    backward_compatibility=True,
) -> dict:
    outputs = list(OutPuts().get())
    output_format_default = outputs[0]
    options = f"""
display:
  description: {_('Display variables and values')}
  help: |-
    {_('Find all the variables and their values in your configuration (structural and user data). Additional informations are available, such as the default value, the location where the value is loaded, etc.')}
  disabled:
    jinja: |-
      {{% if step.output is propertyerror or step.output != 'display' %}}
        true
      {{% else %}}
        false
      {{% endif %}}
    return_type: boolean
    description: {_('if display is not set in "step.output"')}

  output_format:
    description: {_('The output format for displaying variables')}
    default: { output_format_default }
    choices:
"""
    for output in outputs:
        options += f"      - {output}\n"
    options += f"""
  show_secrets: false  # {_('Show secrets instead of obscuring them')}

  console:
    description: {_("Specific configuration for console output")}
    disabled:
      variable: _.output_format
      when_not: console

    max_width:
      description: {_("Maximum number of characters per line")}
      help: {_('null means unlimited')}
      type: integer
      mandatory: false
      params:
        min_integer: 50
"""
    return {
        "name": "display",
        "process": "output",
        "options": options,
        "level": 40,
    }


__all__ = ("get_rougail_config",)
