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

# Copyright 2008-2015 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
from calculate.lib.datavars import ReadonlyVariable
from calculate.lib.utils.common import (getValueFromCmdLine,
                                        getValueFromConfig)

import sys
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate

_ = lambda x: x
setLocalTranslate('cl_lib3', sys.modules[__name__])

__ = getLazyLocalTranslate(_)


class Locale(object):
    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',
        },
        'nl_NL': {
            'name': __('Dutch'),
            'locale': 'nl_NL.UTF-8',
            'keymap': 'nl',
            'dumpkeys_charset': '',
            'consolefont': 'lat9w-16',
            'xkblayout': 'us,nl',
            'language': 'nl_NL',
        },
        'nl_BE': {
            'name': __('Belgian Dutch (Flemish)'),
            'locale': 'nl_BE.UTF-8',
            'keymap': 'nl',
            'dumpkeys_charset': '',
            'consolefont': 'lat9w-16',
            'xkblayout': 'us,nl',
            'language': 'nl_BE',
        },
        '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/"
        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
        locale_file = '/etc/env.d/02locale'
        locale_val = getValueFromCmdLine("calculate", 0)
        if self.isLangExists(locale_val):
            return self.getFieldByLang('locale', locale_val)
        else:
            locale_val = getValueFromConfig(locale_file, 'LANG')
            if self.isValueInFieldExists('locale', locale_val):
                return locale_val
        if "LANG" in os.environ 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):
        locale_xkb = self.Get("os_locale_xkb")
        if locale_xkb:
            return locale_xkb.split("(")[0]
        return ""


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

    def get(self):
        return list(sorted(list(set(self.getLangs()) &
                                {"en_US", "nl_NL", "nl_BE", "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())
