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

#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
#
#  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.

import re
import os
import types
import cl_utils
import cl_base

class fillVars(object, cl_base.glob_attr):

    def get_os_net_domain(self):
        ''' Определим домен'''
        domain=self._runos("hostname -d 2>&1")
        if not domain:
            print _("Error:") + " " +_("Not found domain name")
            print _("Command 'hostname -d' returns an empty value")
            cl_base.exit(1)
        elif re.search("^hostname: ",domain):
            return "local"
        else:
            return domain

    def get_os_linux_shortname(self):
        '''Получить переменную короткого названия системы'''
        path = '/etc/calculate/calculate.ini'
        if os.path.exists(path):
            FD = open(path)
            data = FD.readlines()
            FD.close()
            shortNameList = filter(lambda y:y,
                                   map(lambda x:\
                                       len(x.split("="))==2 and\
                                       x.split("=")[0]=="calculate" and\
                                       x.split("=")[1].strip(), data))
            if shortNameList:
                return shortNameList[0]
        gentooFile = "/etc/gentoo-release"
        shortName = "Linux"
        if os.path.exists(gentooFile):
            shortName = "Gentoo"
        return shortName

    def get_os_linux_name(self):
        """полное название системы"""
        linuxShortName = self.Get("os_linux_shortname")
        if linuxShortName:
            dictLinuxName = {"CLD":"Calculate Linux Desktop",
                             "CLDX":"Calculate Linux Desktop",
                             "CDS":"Calculate Directory Server",
                             "Gentoo":"Gentoo"}
            if linuxShortName in dictLinuxName.keys():
                return dictLinuxName[linuxShortName]
            else:
                return "Linux"
        else:
            return "Linux"

    def get_os_linux_subname(self):
        """постфикс к названию системы"""
        linuxShortName = self.Get("os_linux_shortname")
        if linuxShortName:
            dictLinuxSubName = {"CLD":"KDE", "CLDX":"XFCE"}
            if linuxShortName in dictLinuxSubName.keys():
                return dictLinuxSubName[linuxShortName]
            else:
                return ""
        else:
            return ""

    def get_os_linux_ver(self):
        '''Получить версию системы'''
        path = '/etc/calculate/calculate.ini'
        if os.path.exists(path):
            FD = open(path)
            data = FD.readlines()
            FD.close()
            shortNameList = filter(lambda y:y,
                                   map(lambda x:\
                                       len(x.split("="))==2 and\
                                       x.split("=")[0]=="linuxver" and\
                                       x.split("=")[1].strip(), data))
            if shortNameList:
                return shortNameList[0]
        gentooFile = "/etc/gentoo-release"
        systemVersion = ""
        flagGentoo = False
        if os.path.exists(gentooFile):
            gentooLink = "/etc/make.profile"
            if os.path.islink(gentooLink):
                systemVersion = os.readlink(gentooLink).rpartition("/")[2]
                flagGentoo = True
        if not flagGentoo:
            kernelVersion=self._runos("uname -r")
            if kernelVersion:
                systemVersion = kernelVersion.partition("-")[0]
        return systemVersion

    def get_os_net_hostname(self):
        '''Считать имя компьютера net_host'''
        hostname=self._runos("hostname -s 2>&1")
        if not hostname:
            return ""
        if re.search("^hostname: ",hostname):
            hostname=self._runos("hostname 2>&1")
            if not hostname:
                return ""
        if re.search("^hostname: ",hostname):
            return self.Get('os_linux_shortname')
        else:
            if hostname=='livecd':
                return self.Get('os_linux_shortname')
        return hostname

    # все ip
    def get_os_net_ip(self):
        """все ip компьютера, разделитель запятая"""
        IPs = []
        netInterfaces=cl_utils.getdirlist("/sys/class/net/")
        for i in netInterfaces:
            res = self._runos("/sbin/ifconfig %s"%i)
            if not res:
                break
            for line in res:
                searchIP = re.search('addr:([0-9\.]+).+Bcast:', line)
                if searchIP:
                    # ip адрес
                    ip = searchIP.groups()[0]
                    IPs.append(ip)
        return ",".join(IPs)

    # Разрешенные сети (в данном случае все сети)
    def get_os_net_allow(self):
        """Разрешенные сети разделитель запятая"""
        net={'255.0.0.0':'/8',
            '255.255.0.0':'/16',
            '255.255.255.0':'/24',
            '255.255.255.128':'/25',
            '255.255.255.252':'/30',
            '255.255.255.255':''}
        networks=[]
        netInterfaces=cl_utils.getdirlist("/sys/class/net/")
        flagError = False
        for i in netInterfaces:
            res = self._runos("/sbin/ifconfig %s"%i)
            if not res:
                flagError = True
                break
            for j in res:
                s_ip=re.search('addr:([0-9\.]+).+Bcast:.+Mask:([0-9\.]+)' ,j)
                if s_ip:
                    ip, netmask=s_ip.groups()
                    ip=ip.split('.')
                    if ip[0]=='10' or\
                        (ip[0]=='172' and int(ip[1])>=16 and int(ip[1])<=31)or\
                        (ip[0]=='192' and ip[1]=='168'):
                        if netmask=='255.255.255.255':
                            networks.append(ip)
                        elif netmask=='255.255.255.252':
                            networks.append(ip[0]+"."+ip[1]+"."+ip[2]+"."+\
                                            "252"+net[netmask])
                        elif netmask=='255.255.255.128':
                            networks.append(ip[0]+"."+ip[1]+"."+ip[2]+"."+\
                                            "128"+net[netmask])
                        elif netmask=='255.255.255.0':
                            networks.append(ip[0]+"."+ip[1]+"."+ip[2]+"."+"0"+\
                                            net[netmask])
                        elif netmask=='255.255.0.0':
                            networks.append(ip[0]+"."+ip[1]+".0.0"+net[netmask])
                        elif netmask=='255.0.0.0':
                            networks.append(ip[0]+".0.0.0"+net[netmask])

        if flagError:
            return ""
        return ",".join(networks)

    def get_os_locale_locale(self):
        """локаль (прим: ru_RU.UTF-8)"""
        if os.environ.has_key("LANG"):
            return os.environ["LANG"]
        else:
            return "en_US.UTF-8"

    def get_os_locale_lang(self):
        """язык (прим: ru_RU)"""
        locale = self.Get("os_locale_locale")
        if locale:
            return locale.split(".")[0]
        return ""

    def get_os_locale_language(self):
        """язык (прим: ru)"""
        lang = self.Get("os_locale_lang")
        if lang:
            return lang.split("_")[0]
        return ""

    def get_os_locale_xkb(self):
        """раскладка клавиатуры для X"""
        path = '/etc/conf.d/keymaps'
        mapDict={"by":"us,by",
                 "be-latin1":"be,us",
                 "br-abnt2":"br,us",
                 "cf":"ca,us",
                 "dk-latin1":"dk,us",
                 "fr-latin9":"fr,us",
                 "de-latin1":"de,us",
                 "is-latin1":"is,us",
                 "it":"it,us",
                 "no-latin1":"no,us",
                 "pl":"pl,us",
                 "-u ru4":"us,ru(winkeys)",
                 "es euro2":"es,us",
                 "sv-latin1":"se,us",
                 "ua-utf":"us,ua(winkeys)",
                 "uk":"gb,us",
                 "us":"us"}
        if os.path.exists(path):
            FD = open(path)
            data = FD.readlines()
            FD.close()
            shortNameList = filter(lambda y:y,
                                   map(lambda x:\
                                       len(x.split("="))==2 and\
                                       x.split("=")[0]=="KEYMAP" and\
                                       x.split("=")[1].replace('"',"").strip(),\
                                       data))
            if shortNameList:
                if shortNameList[0] in mapDict.keys():
                    return mapDict[shortNameList[0]]
        lang = self.Get("os_locale_lang")
        # Языки: 
        # Португальский - pt_BR
        # Французский   - fr_FR
        # Немецкий      - de_DE
        # Итальянский   - it_IT
        # Польский      - pl_PL
        # Русский       - ru_RU
        # Испанский     - es_ES
        # Украинский    - uk_UA
        # Английский    - en_US
        xkbDict = {'pt_BR':'br,us',
                'fr_FR':'fr,us',
                'de_DE':'de,us',
                'it_IT':'it,us',
                'pl_PL':'pl,us',
                'ru_RU':'us,ru(winkeys)',
                'es_ES':'es,us',
                'uk_UA':'us,ua(winkeys)',
                'en_US':'us'}
        if lang:
            if xkbDict.has_key(lang):
                return xkbDict[lang]
        return ""

    def get_os_locale_xkbname(self):
        """названия используемых раскладок клавиатуры для X"""
        localeXkb = self.Get("os_locale_xkb")
        if localeXkb:
            return localeXkb.split("(")[0]
        return ""

    def get_os_arch_machine(self):
        """архитектура процессора"""
        march = self._runos("uname -m")
        if not march:
            return ""
        return march

    def get_os_root_dev(self):
        """корневой раздел файловой системы"""
        for record in open('/proc/cmdline','rb').readlines():
            re_res=re.search('^root=(\/dev\/[a-z]+[0-9]).*',record.strip())
            if re_res:
                return re_res.group(1)
            else:
                mountLunes = self._runos("mount")
                if not mountLunes:
                    return ""
                if type(mountLunes) == types.ListType:
                    root_dev = mountLunes[0].split("on / type")[0].strip()
                    if root_dev:
                        return root_dev
                return ""

    def get_os_root_type(self):
        """тип носителя (ram, hdd, livecd)"""
        mountLunes = self._runos("mount")
        if not mountLunes:
            return ""
        rootType = "hdd"
        if type(mountLunes) == types.ListType:
            flagCD = False
            for line in mountLunes:
                if "/dev/loop0 on / type" in line:
                    rootType = "ram"
                    break
                elif "/dev/loop0 on /newroot/mnt/livecd type" in line:
                    rootType = "ram"
                    flagCD = True
                    break
            if rootType == "ram":
                if os.path.exists("/mnt/livecd") or flagCD:
                    rootType = "livecd"
                    return rootType
            rootDev = self.Get("os_root_dev")
            if rootType != "ram" and rootDev:
                slpRootDev = rootDev.split("/dev/")
                if len(slpRootDev) == 2:
                    rDev = slpRootDev[1]
                    devLines = self._runos("ls -la /dev/disk/by-id/", None,
                                           {"LANG":"C"})
                    if not devLines:
                        return ""
                    if type(devLines) == types.ListType:
                        for line in devLines:
                            if rDev in line and "usb-" in line:
                                rootType = "usb-hdd"
                                break
            if rootType == "ram":
                rootType = "hdd"
            return rootType
        else:
            return ""

    def get_hr_virtual(self):
        """Название виртуальной машины (virtualbox, vmware, qemu)"""
        pciLines = self._runos("/usr/sbin/lspci")
        if not pciLines:
            return False
        virtSysDict = {'VirtualBox':'virtualbox',
                       'VMware':'vmware',
                       'Qumranet':'qemu'}
        virtName = ''
        for vName in virtSysDict.keys():
            if filter(lambda x: vName in x, pciLines):
                virtName = virtSysDict[vName]
                break
        return virtName
