#!/usr/bin/env python3
"""
Silique (https://www.silique.fr)
Copyright (C) 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 rougail.object_model import CONVERT_OPTION
from rougail.config import RougailConfig
from tiramisu.error import ValueOptionError

class RougailUserDataEnvironment:
    def __init__(self,
                 config: 'Config',
                 *,
                 rougailconfig: RougailConfig=None,
                 ):
        self.config = config
        if rougailconfig is None:
            rougailconfig = RougailConfig
            user_data = rougailconfig['step.user_data']
            if 'environment' not in user_data:
                user_data.append('environment')
                rougailconfig['step.user_data'] = user_data
        user_data = rougailconfig['step.user_data']
        if 'environment' not in user_data:
            raise Exception('environment is not set in step.user_data')
        self.rougailconfig = rougailconfig
        self.errors = []
        self.warnings = []

    def run(self):
        self.config.property.read_write()
        if self.rougailconfig['environment.mandatory']:
            current_titles = []
            while True:
                mandatories = self.config.value.mandatory()
                if not mandatories:
                    break
                mandatory = mandatories[0]
                path = mandatory.path()
                if '.' in path:
                    current_config = self.config
                    for idx, p in enumerate(path.split('.')[0:-1]):
                        current_config = current_config.option(p)
                        if idx < len(current_titles):
                            if current_titles[idx] == p:
                                continue
                            current_titles = current_titles[0:idx]
                        current_titles.append(p)
                        self.print(current_config.description(), idx)
                self.display_environment(mandatory)
        else:
            self.parse(self.config)
        self.config.property.read_only()

    def parse(self, config, title_level=0):
        for option in config:
            if option.isoptiondescription():
                self.print(option.description(), title_level)
                self.parse(option, title_level + 1)
            else:
                self.display_environment(option)

    def print(self, title, title_level):
        qprint(' ' * title_level + 'đź“‚ ' + title, 'bold')

    def display_environment(self, option):
        kwargs = {}
        option_type = option.information.get('type')
        isdefault = option.owner.isdefault()
        default = option.value.get()
        ismulti = option.ismulti()
        type_obj = None
        type_obj = CONVERT_OPTION.get(option_type, {}).get("func")

        from .helper import get_rougail_environment_var, get_rougail_environment_dict
        rougail_environment_var = get_rougail_environment_var()
        option_name = option.path()
        if option_name in rougail_environment_var:
            option.value.set(get_rougail_environment_dict()[option_name])        
        #option.value.set(["78", "52"])
        # TODO 
        # - tester les var commençant par ROUGAIL_
        # 'ROUGAIL_'
        # tester si c'est une multi
        # le CONVERT_TYPE ne marchera pas si c'est une multi
        # récupérer le nam de l'option pour voir si elle est dans l'env
        
        
        
        #RougailValidator.option = option
        #RougailValidator.option_type = {'type': option_type,
        #                                'func': type_obj,
        #                                }
        #RougailValidator.ismulti = ismulti
        #if option_type == 'choice':
        #    question_funtion = select
        #    #RougailValidator.default = default
        #    kwargs['choices'] = option.value.list()
        #elif option_type == 'boolean':
        #    question_funtion = confirm
        #else:
        #    question_funtion = text
        #    kwargs['validate'] = RougailValidator
        #args = ['đź““ ' + option.description()]
        #if ismulti:
        #    kwargs['multiline'] = True
        #    if default:
        #        kwargs['default'] = "\n".join(default)
        #elif default is not None:
        #    kwargs['default'] = default
        #value = RougailValidator().convert_value(question_funtion(*args, **kwargs).ask(), False)
        #if isdefault and value == default:
        #    option.value.reset()
        #else:
        #    option.value.set(value)


#class RougailValidator(Validator):
#    def validate(self, document):
#        return self.convert_value(document.text)
#
#    def convert_value(self,
#                      document,
#                      validate=True,
#                      ):
#        if not self.ismulti:
#            value = self._convert_a_value(document, document, validate)
#        else:
#            value = []
#            if document is not None:
#                for val in document.strip().split('\n'):
#                    val = self._convert_a_value(val, document, validate)
#                    if val is not None:
#                        value.append(val)
#        if validate:
#            try:
#                self.option.value.set(value)
#            except ValueOptionError as err:
#                err.prefix = ''
#                raise ValidationError(
#                    message=str(err),
#                    cursor_position=len(document),
#                )
#        return value
#
#    def _convert_a_value(self, value, document, validate):
#        if value is None:
#            if self.option_type['type'] == 'choice':
#                return self.default
#            return
#        if isinstance(value, str):
#            value = value.strip()
#        if value == '':
#            if validate and "mandatory" in self.option.property.get():
#                raise ValidationError(
#                    message=f"Value must not be empty",
#                    cursor_position=len(document),
#                )
#            return
#        if self.option_type['func']:
#            try:
#                return self.option_type['func'](value)
#            except:
#                raise ValidationError(
#                    message=f"Not a valid {self.option_type['type']}",
#                    cursor_position=len(document),
#                )
#        return value