#!/usr/bin/env python3

"""
Cuchulufm is a series of wrappers for bottle.py, mako and others and construct a simple headless cms.

Copyright (C) 2024 Antonio de la Rosa Caballero

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero 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 Affero General Public License for more details.

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

from importlib import import_module
from cuchulu.libraries.sessionplugin import get_session
import json
from bottle import request
import gettext
import os

yes_session=False

i18n_module={}

def load_lang(*args):
    """A function for load the lang module dinamically
    """
    
    for module in args:
        
        lang_path=module[0]+'.i18n.'+module[1]
        
        try:
            
            i18n_module[lang_path]=import_module(lang_path)
            
            pass
        
        except:
            pass
        
       # here load the language 
        
class PGetText:
    
    # Dict where all gettext domain are saved -> domain=name, example, admin, libraries, pastafari2, etc...
    
    l={}
    
    def __init__(self, module_file):
        
        module_dir=os.path.dirname(os.path.realpath(module_file))
        
        module_name=os.path.basename(module_dir)
        
        if module_name not in PGetText.l:
            
            PGetText.l[module_name]={}
        
            for i in I18n.dict_i18n:
        
                if i not in PGetText.l[module_name]:
                    
                    PGetText.l[module_name][i]=gettext.translation(module_name, module_dir+'/languages/', languages=[i], fallback=True)
                    PGetText.l[module_name][i].install()
                    
        self.module=module_name
        
    def gettext(self, text):
        
        return PGetText.l[self.module][I18n.get_default_lang()].gettext(text)

def pgettext(module_file):
    
    module=os.path.dirname(os.path.realpath(module_file))
    
    base_name=os.path.dirname(os.path.realpath(module))
    
    l=gettext.translation(os.path.basename(base_name), module+'/languages/', languages=I18n.get_default_lang(), fallback=True)
    
    return l.gettext

class I18n:
    
    """Class for i18n tasks
    
    Class for i18n tasks, how, strings for every language supported, for now are en-US and es-ES. You can add more languages adding 
    
    Attributes:
        default_lang (str): The default string lang used when get someone
        dict_i18n (list): The list with default languages. You can add more calling it static variable in settings/config.py
        
    """
    
    default_lang='en-US'
    
    dict_i18n=['en-US', 'es-ES']
    
    l={}
    
    def __init__(self, module):
        
        self.module=module
    
    def clang(self, module, symbol, text_default):
        """Static method for get a string from selected language
        
        Static method used to get the string of the selected language. If there is no string in the selected language, it returns text_default.
        
        Args:
            module (str): The module to which the translation string belongs 
            symbol (str): Simple symbol that is useful for identify the string
            text_default (str): The text used by default when there are not translation in the selected language 
        """
        
        #if not lang:
        #    lang=I18n.get_default_lang()
        
        lang=self.default_lang
        
        I18n.l[lang]=I18n.l.get(lang, {})
        
        I18n.l[lang][module]=I18n.l[lang].get(module, {})
        
        I18n.l[lang][module][symbol]=I18n.l[lang][module].get(symbol, text_default)
        
        return I18n.l[lang][module][symbol]
    
    def slang(self, symbol, text_default, lang=None):
        """Method for get a string from selected language but object oriented
        
        Method for get a string from selected language but object oriented
        
        Args:
            symbol (str): The symbol used for identify the text string.
            text_default (str): The text default used. You have use how base for translations. 
        """
        return I18n.lang(self.module, symbol, text_default, lang)
    
    def tlang(self, text_default, lang=None):
        """Method for get a string from selected language but object oriented and using module and symbol by default
        
        Method for get a string from selected language but object oriented and using module and symbol by default
        
        Args:
            symbol (str): The symbol used for identify the text string.
            text_default (str): The text default used. You have use how base for translations. 
        """
        
        symbol=text_default[:60]
        
        return I18n.lang(self.module, symbol, text_default, lang)
        
    
    @staticmethod
    def add_lang(lang, module, symbol, text):
        
        I18n.l[lang]=I18n.l.get(lang, {})

        I18n.l[lang][module]=I18n.l[lang].get(module, {})

        I18n.l[lang][module][symbol]=text
    
    #@staticmethod 
    #def set_lang(code_lang):
    #    if default_lang
        
    
    @staticmethod
    def get_default_lang():
        """Static method for get the default lang"""
        
        lang=I18n.default_lang
        
        s=get_session()

        lang=s.get('lang', lang)
            
        return lang
    
    @staticmethod
    def lang(module, symbol, text_default, lang=None):
        """Static method for get a string from selected language
        
        Static method used to get the string of the selected language. If there is no string in the selected language, it returns text_default.
        
        Args:
            module (str): The module to which the translation string belongs 
            symbol (str): Simple symbol that is useful for identify the string
            text_default (str): The text used by default when there are not translation in the selected language 
        """
        
        if not lang:
            lang=I18n.get_default_lang()
        
        I18n.l[lang]=I18n.l.get(lang, {})
        
        I18n.l[lang][module]=I18n.l[lang].get(module, {})
        
        I18n.l[lang][module][symbol]=I18n.l[lang][module].get(symbol, text_default)
        
        return I18n.l[lang][module][symbol]

    @staticmethod
    def extract_value(value):
        """Static method for get values from json lang array
        
        Args:
            value (json): Lang dict in json format
        """
        
        value=json.loads(value)

        lang=I18n.get_default_lang()
        
        if value[lang]!='':
        
            return value[lang]

        return value[I18n.default_lang]

    @staticmethod
    def get_browser_lang():
        """Method for get the language from user browser"""
        
        return request.headers.get('Accept-Language', 'en-US')

    @staticmethod
    def lang_json(module, symbol, text_default):
        
        arr_final={}
        
        for l in I18n.dict_i18n:
            arr_final[l]=I18n.lang(module, symbol, text_default, l)
        
        return json.dumps(arr_final)

common_pgettext=PGetText(__file__)
