#-*- 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.

import os
import socket
import pwd
import grp
from os import environ,path
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable
from calculate.lib.cl_vars_share import varsShare
from calculate.lib.utils.common import getPasswdUsers,isBootstrapDataOnly
from calculate.lib.utils.files import listDirectory
import sys
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_lib3',sys.modules[__name__])

try:
    from calculate.lib.cl_ldap import ldapUser,ldap
except ImportError:
    ldapUser = None

class LdapHelper:
    # data object from LDAP
    _ldapUserObject = False
    # user data from LDAP
    _ldapUserData = {}

    def getUserInfo(self,userName):
        """Get information about user from LDAP in dict format"""
        if userName:
            if userName in LdapHelper._ldapUserData:
                return LdapHelper._ldapUserData[userName]
            elif not ldapUser is None:
                ldapObj = self.getLdapUserObject()
                if ldapObj:
                    userInfo = ldapObj.getUserLdapInfo(userName)
                    if userInfo:
                        LdapHelper._ldapUserData[userName] = userInfo
                        return userInfo
        return {}

    def getLdapUserObject(self):
        """Get data obejct from LDAP"""
        if not LdapHelper._ldapUserObject and ldapUser:
            LdapHelper._ldapUserObject = ldapUser()
        return LdapHelper._ldapUserObject

    def getLdapUserlist(self):
        """
        Get userlist from LDAP
        """
        userObj = self.getLdapUserObject()
        if userObj and userObj.connectLdap():
            return map(lambda x:x[0][1]['uid'][0],
                   userObj.ldapObj.ldapSearch(
                   userObj.getUsersDN(),
                   ldap.SCOPE_ONELEVEL,'(objectClass=*)',
                   ['uid']))
        return []

class VariableUrLogin(Variable,LdapHelper):
    """
    User Login
    """
    type = "choiceedit"
    opt = ["ur_login"]
    metavalue = "USER"
    untrusted = True

    def init(self):
        self.help = _("username")
        self.label = _("User name")

    def choice(self):
        return [""]+sorted(list(set(
                    self.getLdapUserlist()+getPasswdUsers())))

    def check(self,value):
        """Does user exist"""
        if value == "":
            raise VariableError(_("Need to specify user"))
        try:
            pwd.getpwnam(value).pw_gid
        except:
            raise VariableError(_("User %s does not exist")%value)

    def get(self):
        if self.Get('cl_action') == "desktop":
            return ""
        try:
            user = environ['USER']
            pwd.getpwnam(user)
            return user
        except:
            uid = os.getuid()
            try:
                userName = pwd.getpwuid(uid).pw_name
            except:
                return ""
            return userName

class VariableUrGroup(ReadonlyVariable):
    """
    User group name
    """
    def get(self):
        gid = self.Get('ur_gid')
        groupName = ""
        try:
            groupName = grp.getgrgid(gid).gr_name
        except:
            return ""
        return groupName

class VariableUrGid(ReadonlyVariable):
    """
    User GID
    """
    type = "int"

    def get(self):
        userName = self.Get('ur_login')
        if userName:
            try:
                return str(pwd.getpwnam(userName).pw_gid)
            except:
                return ""
        return ""

class VariableUrUid(ReadonlyVariable):
    """
    User GID
    """
    type = "int"

    def get(self):
        userName = self.Get('ur_login')
        if userName:
            try:
                return str(pwd.getpwnam(userName).pw_uid)
            except:
                return ""
        else:
            return ""

class VariableUrFullname(ReadonlyVariable):
    """
    User fullname
    """
    def get(self):
        userName = self.Get('ur_login')
        fullName = ""
        if userName:
            try:
                fullName = pwd.getpwnam(userName).pw_gecos
            except:
                return ""
        return fullName

class VariableUrHomePath(ReadonlyVariable):
    """
    User home directory
    """
    def get(self):
        """Get user home directory"""
        userName = self.Get('ur_login')
        homeDir = ""
        if userName:
            try:
                homeDir = pwd.getpwnam(userName).pw_dir
            except:
                return ""
        return homeDir

class VariableUrJid(ReadonlyVariable,LdapHelper):
    """
    User Jabber id (Get from LDAP)
    """
    def get(self):
        """Get user Jabber id"""
        userInfo = self.getUserInfo(self.Get('ur_login'))
        userJID = ""
        if userInfo:
            userJID = userInfo["jid"] 
        return userJID

class VariableUrMail(ReadonlyVariable,LdapHelper):
    """
    User email (Get from LDAP)
    """
    def get(self):
        userInfo = self.getUserInfo(self.Get('ur_login'))
        userMail = ""
        if userInfo:
            userMail = userInfo["mail"] 
        return userMail

class VariableClHomeCryptSet(Variable):
    """
    Вкл/выкл шифрование пользовательских профилей
    """
    value = "off"

    type  = "bool"

class VariableUrHomeCryptSet(ReadonlyVariable):
    """
    Шифрованный или нет пользовательский профиль
    """
    type  = "bool"

    def get(self):
        # если у пользователский профиль настроен как шифрованный
        login = self.Get('ur_login')
        if login == "root":
            return "off"
        cryptPath = path.join('/home/.ecryptfs',login,'.ecryptfs')
        if path.exists(cryptPath):
            return "on"
        # если пользовательского профиля нет, то шифровать ли профиль
        # узнаем на уровне системы
        homeDir = self.Get('ur_home_path')
        if (not path.exists(homeDir) or not listDirectory(homeDir) or
            isBootstrapDataOnly(homeDir)):
            return self.Get('cl_home_crypt_set')
        # профиль не шифрованный
        return "off"
