#-*- coding: utf-8 -*-

# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

from os import path
import os
import socket
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable
from calculate.lib.utils.common import (getValueFromCmdLine,
                getValueFromConfig)

import sys
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate
setLocalTranslate('cl_lib3',sys.modules[__name__])

__ = getLazyLocalTranslate(_)

class Locale:
    langData = {
    'be_BY' : {
                'name':__('Belarussian'),
                'locale':'be_BY.UTF-8',
                'keymap':'by',
                'dumpkeys_charset': 'koi8-u',
                'consolefont':'Cyr_a8x16',
                'xkblayout':'us,by',
                'language':'be',
        },
    'bg_BG' : {
                'name':__('Bulgarian'),
                'locale':'bg_BG.UTF-8',
                'keymap':'bg_bds-utf8',
                'dumpkeys_charset': '',
                'consolefont':'ter-m14n',
                'xkblayout':'us,bg',
                'language':'bg',
        },
    'fr_BE' : {
                'name':__('Belgian'),
                'locale':'fr_BE.UTF-8',
                'keymap':'be-latin1',
                'dumpkeys_charset':'',
                'consolefont':'lat9w-16',
                'xkblayout':'us,be',
                'language':'fr',
        },
    'pt_BR' : {
                'name':__('Brazilian Portuguese'),
                'locale':'pt_BR.UTF-8',
                'keymap':'br-abnt2',
                'dumpkeys_charset':'',
                'consolefont':'lat9w-16',
                'xkblayout':'pt,us',
                'language':'pt_BR',
        },
    'fr_CA' : {
                'name':__('Canadian French'),
                'locale':'fr_CA.UTF-8',
                'keymap':'cf',
                'dumpkeys_charset':'',
                'consolefont':'default8x16',
                'xkblayout':'us,ca_enhanced',
                'language':'fr',
        },
    'da_DK' : {
                'name':__('Danish'),
                'locale':'da_DK.UTF-8',
                'keymap':'dk-latin1',
                'dumpkeys_charset':'',
                'consolefont':'lat0-16',
                'xkblayout':'us,dk',
                'language':'da',
        },
    'fr_FR' : {
                'name':__('French'),
                'locale':'fr_FR.UTF-8',
                'keymap':'fr-latin9',
                'dumpkeys_charset':'',
                'consolefont':'lat0-16',
                'xkblayout':'fr,us',
                'language':'fr',
        },
    'de_DE' : {
                'name':__('German'),
                'locale':'de_DE.UTF-8',
                'keymap':'de-latin1',
                'dumpkeys_charset':'',
                'consolefont':'lat9w-16',
                'xkblayout':'de,us',
                'language':'de',
        },
    'is_IS' : {
                'name':__('Icelandic'),
                'locale':'is_IS.UTF-8',
                'keymap':'is-latin1',
                'dumpkeys_charset':'',
                'consolefont':'cp850-8x16',
                'xkblayout':'us,is',
                'language':'is',
        },
    'it_IT' : {
                'name':__('Italian'),
                'locale':'it_IT.UTF-8',
                'keymap':'it',
                'dumpkeys_charset':'',
                'consolefont':'default8x16',
                'xkblayout':'us,it',
                'language':'it',
        },
    'nn_NO' : {
                'name':__('Norwegian'),
                'locale':'nn_NO.UTF-8',
                'keymap':'no-latin1',
                'dumpkeys_charset':'',
                'consolefont':'lat9w-16',
                'xkblayout':'us,no',
                'language':'nn',
        },
    'pl_PL' : {
                'name':__('Polish'),
                'locale':'pl_PL.UTF-8',
                'keymap':'pl',
                'dumpkeys_charset':'',
                'consolefont':'lat2-16',
                'xkblayout':'us,pl',
                'language':'pl',
        },
    'pt_PT' : {
                'name':__('Portuguese'),
                'locale':'pl_PL.UTF-8@euro',
                'keymap':'pt-latin9',
                'dumpkeys_charset':'',
                'consolefont':'lat0-16',
                'xkblayout':'pt,us',
                'language':'pt',
        },
    'ro_RO' : {
                'name':__('Romanian'),
                'locale':'ro_RO.UTF-8',
                'keymap':'ro_win',
                'dumpkeys_charset':'',
                'consolefont':'lat2-16',
                'xkblayout':'ro,us',
                'language':'ro',
        },
    'ru_RU' : {
                'name':__('Russian'),
                'locale':'ru_RU.UTF-8',
                'keymap':'-u ruwin_cplk-UTF-8',
                'dumpkeys_charset':'',
                'consolefont':'ter-k14n',
                'xkblayout':'us,ru(winkeys)',
                'language':'ru',
        },
    'es_ES' : {
                'name':__('Spanish'),
                'locale':'es_ES.UTF-8',
                'keymap':'es euro2',
                'dumpkeys_charset':'',
                'consolefont':'lat0-16',
                'xkblayout':'es,us',
                'language':'es',
        },
    'sv_SE' : {
                'name':__('Swedish'),
                'locale':'sv_SE.UTF-8',
                'keymap':'sv-latin1',
                'dumpkeys_charset':'',
                'consolefont':'lat0-16',
                'xkblayout':'us,se',
                'language':'sv',
        },
    'uk_UA' : {
                'name':__('Ukrainian'),
                'locale':'uk_UA.UTF-8',
                'keymap':'ua-utf',
                'dumpkeys_charset':'koi8-u',
                'consolefont':'ter-v14n',
                'xkblayout':'us,ua(winkeys)',
                'language':'ua',
        },
    'en_GB' : {
                'name':__('United Kingdom/British'),
                'locale':'en_GB.UTF-8',
                'keymap':'uk',
                'dumpkeys_charset':'',
                'consolefont':'LatArCyrHeb-16',
                'xkblayout':'us,gb',
                'language':'en',
        },
    'en_US' : {
                'name':__('United States/English'),
                'locale':'en_US.UTF-8',
                'keymap':'us',
                'dumpkeys_charset':'',
                'consolefont':'LatArCyrHeb-16',
                'xkblayout':'us',
                'language':'en',
        }
    }

    def getLangs(self):
        return self.langData.keys()

    def getLanguages(self):
        return map(lambda x:self.langData[x]['language'],
                   self.langData.keys())

    def isLangExists(self,lang):
        return lang in self.langData.keys()

    def isValueInFieldExists(self,field,value):
        return value in map(lambda x:self.langData[x][field],
                        self.langData.keys())

    def getFields(self,field):
        return [ l[1][field] for l in self.langData.items() ]

    def getFieldByLang(self,field,lang):
        return self.langData.get(lang, self.langData['en_US'])[field]

    def getFieldByKeymap(self,field,keymap):
        return self.langData.get(self.getLangByField('keymap',keymap),
                                self.langData['en_US'])[field]

    def getLangByField(self,field,value):
        langs = [lang[0] for lang in self.langData.items() 
                    if lang[1][field] == value ]
        if not langs:
            return 'en_US'
        else:
            return langs[0]

class VariableOsClockTimezone(ReadonlyVariable):
    """
    Current timezone
    """
    def get(self):
        zoneinfodir = "/usr/share/zoneinfo/"
        localtimefile = "/etc/localtime"
        timezonefile = "/etc/timezone"
        # try get timezone from kernel calculate param
        timezone = getValueFromCmdLine("calculate",2)
        if timezone and \
            path.exists(path.join(zoneinfodir,timezone)):
            return timezone
        # get timezone from /etc/timezone
        if path.exists(timezonefile):
            return open(timezonefile,"r").read().strip()
        return "UTC"

class VariableOsLocaleLocale(ReadonlyVariable,Locale):
    """
    Locale (example: ru_RU.UTF-8)
    """

    def get(self):
        # get locale from boot calculate param
        localeFile = '/etc/env.d/02locale'
        localeVal = getValueFromCmdLine("calculate",0)
        if self.isLangExists(localeVal):
            return self.getFieldByLang('locale',localeVal)
        else:
            localeVal = getValueFromConfig(localeFile,'LANG')
            if self.isValueInFieldExists('locale',localeVal):
                return localeVal
        if os.environ.has_key("LANG") and os.environ["LANG"] != "C":
            return os.environ["LANG"]
        return self.getFieldByLang("locale","default")

class VariableOsLocaleLang(ReadonlyVariable,Locale):
    """
    Language (example: ru_RU)
    """
    def get(self):
        """lang (example: ru_RU)"""
        return self.getLangByField("locale",self.Get('os_locale_locale'))

class VariableOsLocaleLanguage(ReadonlyVariable,Locale):
    """
    Short lang name (example: ru)
    """
    def get(self):
        return self.getFieldByLang("language",self.Get('os_locale_lang'))

class VariableOsLocaleXkb(ReadonlyVariable,Locale):
    """
    Keyboard layout for X server (example: us,ru)
    """
    def get(self):
        """xkb layouts (example: en,ru)"""
        return self.getFieldByLang("xkblayout", self.Get('os_locale_lang'))

class VariableOsLocaleXkbname(ReadonlyVariable,Locale):
    """
    Keyboard layout name for X server (remove value in hooks)
    """
    def get(self):
        localeXkb = self.Get("os_locale_xkb")
        if localeXkb:
            return localeXkb.split("(")[0]
        return ""

class VariableOsLang(ReadonlyVariable,Locale):
    """
    Supported langs
    """
    type = "list"

    def get(self):
        return list(sorted(list(set(self.getLangs()) &
            set(["en_US","de_DE","es_ES","fr_FR","it_IT","pl_PL","pt_BR",
                "uk_UA","bg_BG","ru_RU","ro_RO","pt_PT"]))))

    def humanReadable(self):
        return map(lambda x:self.getFieldByLang("name",x),
               self.Get())
