"""Rougail method

Created by:
EOLE (http://eole.orion.education.fr)
Copyright (C) 2005-2018

Forked by:
Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021

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

distribued with GPL-2 or later license

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
"""
from tiramisu import Config
from tiramisu.error import PropertiesOptionError
from warnings import warn
from typing import List

from .convert import RougailConvert
from .config import RougailConfig
from .update import RougailUpgrade
from .object_model import CONVERT_OPTION
from .utils import normalize_family


def tiramisu_display_name(kls, subconfig) -> str:
    """Replace the Tiramisu display_name function to display path + description"""
    doc = kls._get_information(subconfig, "doc", None)
    comment = f" ({doc})" if doc and doc != kls.impl_getname() else ""
    if "{{ suffix }}" in comment:
        comment = comment.replace('{{ suffix }}', str(subconfig.suffixes[-1]))
    path = kls.impl_getpath()
    if "{{ suffix }}" in path:
        path = path.replace('{{ suffix }}', normalize_family(str(subconfig.suffixes[-1])))
    return f"{path}{comment}"


class Rougail:
    """Main Rougail object"""

    def __init__(
        self,
        rougailconfig=None,
    ) -> None:
        if rougailconfig is None:
            rougailconfig = RougailConfig
        self.rougailconfig = rougailconfig
        self.converted = RougailConvert(self.rougailconfig)
        self.config = None

    def add_path_prefix(
        self,
        path_prefix: str,
    ) -> None:
        """Add a prefix"""
        self.converted.load_config()
        self.converted.parse_directories(path_prefix)

    def run(self):
        """Get Tiramisu Config"""
        if not self.config:
            tiram_obj = self.converted.save(self.rougailconfig["tiramisu_cache"])
            optiondescription = {}
            custom_types = {custom.__name__: custom for custom in self.rougailconfig["custom_types"].values()}
            exec(tiram_obj, custom_types, optiondescription)  # pylint: disable=W0122
            self.config = Config(
                optiondescription["option_0"],
                display_name=tiramisu_display_name,
            )
            self.config.property.read_write()
        return self.config

    def get_config(self):
        warn("get_config is deprecated, use run instead", DeprecationWarning, stacklevel=2)
        return self.run()

    def user_datas(self,
                   user_datas: List[dict]):
        values = {}
        errors = []
        warnings = []
        for datas in user_datas:
            for name, data in datas.get('values', {}).items():
                values.setdefault(name, {}).update(data)
            errors.extend(datas.get('errors', []))
            warnings.extend(datas.get('warnings', []))
        while values:
            value_is_set = False
            for option in self.config:
                if option.path() in values and option.index() in values[option.path()]:
                    try:
                        option.value.set(values[option.path()])
                        value_is_set = True
                        values.pop(option.path())
                    except:
                        pass
            if not value_is_set:
                break
        for path, data in values.items():
            for index, value in data.items():
                try:
                    print('attention', path, value)
                    self.config.option(path).value.set(value)
                    print('pfff')
                except AttributeError as err:
                    errors.append(str(err))
                except ValueError as err:
                    errors.append(str(err).replace('"', "'"))
                except PropertiesOptionError as err:
    #                warnings.append(f'"{err}" but is defined in "{self.filename}"')
                    warnings.append(str(err))
        return {'errors': errors,
                'warnings': warnings,
                }

__all__ = ("Rougail", "RougailConfig", "RougailUpgrade")
