"""
Silique (https://www.silique.fr)
Copyright (C) 2024-2025
            
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 typing import Optional

from .utils import _


class Examples:  # pylint: disable=no-member,too-few-public-methods
    """Build examples"""

    def __init__(self):
        self.examples = None
        self.examples_mandatories = None

    def gen_doc_examples(self):
        """Return examples"""
        self._build_examples()
        return_string = ""
        if self.examples_mandatories:
            return_string += self.formater.title(
                _("Example with mandatory variables not filled in"), self.level
            )
            return_string += self.formater.yaml(self.examples_mandatories)
        if self.examples:
            return_string += self.formater.title(
                _("Example with all variables modifiable"), self.level
            )
            return_string += self.formater.yaml(self.examples)
        return return_string

    def _build_examples(self):
        self.examples, self.examples_mandatories = self._parse_examples(
            self.informations
        )

    def _parse_examples(self, dico, dyn_parent: Optional[str] = None) -> tuple:
        examples = {}
        examples_mandatories = {}
        for value in dico.values():
            if value["type"] == "variable":
                self._parse_examples_variable(
                    value, dyn_parent, examples, examples_mandatories
                )
            else:
                self._parse_examples_family(
                    value, dyn_parent, examples, examples_mandatories
                )
        return examples, examples_mandatories

    def _parse_examples_variable(
        self,
        variable,
        dyn_parent: Optional[str],
        examples: dict,
        examples_mandatories: dict,
    ) -> None:
        for idx, path in enumerate(variable["paths"]):
            if dyn_parent is not None and not path.startswith(dyn_parent):
                continue
            name = variable["names"][idx]
            value = variable["example"][idx]
            examples[name] = value
            if variable["mandatory_without_value"]:
                examples_mandatories[name] = value
            break

    def _parse_examples_family(
        self,
        family,
        dyn_parent: Optional[str],
        examples: dict,
        examples_mandatories: dict,
    ) -> None:
        for idx, path in enumerate(family["informations"]["paths"]):
            if dyn_parent is not None and not path.startswith(dyn_parent):
                continue
            name = family["informations"]["names"][idx]
            if family["type"] == "leadership":
                func = self._parse_examples_leadership
            else:
                func = self._parse_examples
            ret_e, ret_m = func(
                family["children"],
                path + "." if family["type"] == "dynamic" else dyn_parent,
            )
            if ret_m:
                examples_mandatories[name] = ret_m
            if ret_e:
                examples[name] = ret_e

    def _parse_examples_leadership(
        self, leadership, dyn_parent: Optional[str] = None
    ) -> tuple:
        examples = []
        examples_mandatories = []
        leader = next(iter(leadership.values()))
        for path_idx, path in enumerate(leader["paths"]):
            if dyn_parent is not None and not path.startswith(dyn_parent):
                continue
            for leader_idx in range(len(leader["example"][path_idx])):
                examples.append(
                    {
                        follower["names"][path_idx]: follower["example"][path_idx][
                            leader_idx
                        ]
                        for follower in leadership.values()
                    }
                )
                if leader["mandatory_without_value"]:
                    examples_mandatories.append(
                        {
                            follower["names"][path_idx]: follower["example"][path_idx][
                                leader_idx
                            ]
                            for follower in leadership.values()
                            if follower["mandatory_without_value"]
                        }
                    )
            break
        return examples, examples_mandatories