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

# Copyright 2008-2012 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 sys
from os import path
from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable
from calculate.lib.utils.files import readLinesFile
from calculate.lib.utils.common import getValueFromCmdLine
from calculate.lib.utils.ip import isOpenPort
import ldap
from calculate.lib.cl_ldap import ldapUser
from calculate.lib.variables.user import LdapHelper

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

class VariableClRemoteHost(Variable):
    """
    IP or domain name of CDS
    """
    value = ""

class VariableClRemoteHostNew(Variable):
    """
    IP or domain name of CDS
    """
    opt = ["cl_remote_host_new"]
    metavalue = "DOMAIN"
    type = "choiceedit"
    value = ""
    untrusted = True

    def init(self):
        self.label = _("Domain IP")
        self.help = _("domain")

    def check(self,value):
        if self.Get('cl_client_mount_set') == 'off':
            if self.Get('cl_localhost_set') == 'off':
                if self.Get('cl_remote_host') == '':
                    if not value:
                        raise VariableError(_("Need to specify the domain"))
                    elif not isOpenPort(value,445):
                        raise VariableError(
                            _("The specified address is not available"))

class VariableClRemoteHostLive(ReadonlyVariable):
    """
    Remote host from /proc/cmdline param domain
    """
    def get(self):
        return getValueFromCmdLine("calculate","domain") or ""


class VariableOsRemoteAuth(Variable):
    """
    Client work mode (local or hostname)
    """


class VariableOsRemoteClient(Variable):
    """
    Version which apply templates
    """
    pass


class VariableClRemotePw(Variable):
    """
    Client password
    """
    type = "onepassword"
    opt = ["--domain-password"]

    def init(self):
        self.label = _("Domain password")
        self.help = _("specify the domain password")

    def get(self):
        return getValueFromCmdLine("calculate","domain_pw") or ""

class VariableClMovedSkipPath(Variable):
    """
    Skip "Moved" path
    """
    type = "list"
    value = ['Disks','Home','Moved','FTP','Desktop', 'Share']

class VariableClSyncSkipPath(Variable):
    """
    Skip sync path
    """
    type = "list"
    value = [".googleearth", "Home", "Disks", "FTP",
        'Share', ".local/share/akonadi/db_data", ".VirtualBox",
        ".mozilla/firefox/calculate.default/urlclassifier3.sqlite",
        ".local/share/mime/mime.cache", ".gvfs",
        ".kde4/share/apps/nepomuk/repository/main/data", ".logout",
        ".Xauthority", ".thumbnails", ".mozilla/firefox/*/Cache",
        ".kde4/socket-*", ".cache/", ".local/share/Trash"]

class VariableClSyncDelPath(Variable):
    """
    Removed path on sync
    """
    type = "list"
    value = [".kde4/share/config/phonondevicesrc",
             ".kde4/cache-*", ".kde4/tmp-*"]

class VariableClProfileAllSet(Variable):
    type = "bool"
    value = "off"

class VariableClClientSync(Variable):
    type = "bool"
    value = "on"
    metavalue = "ON/OFF"

    opt = ["--sync"]

    def init(self):
        self.label = _("Synchronize the user profile")
        self.help = _("synchronize user preferences")

class VariableClLocalhostSet(Variable):
    """
    Using autopartition
    """
    type = "bool"
    element = "radio"
    value = "off"
    opt = ["-r"]
    metavalue = "ON/OFF"

    def init(self):
        self.label = _("Computer role")
        self.help = _("remove the domain connection settings")

    def choice(self):
        return [("off",_("Domain workstation")),
                ("on",_("Local workstation"))]

    def check(self,value):
        if self.Get('cl_remote_host') == '' and value == "on":
            raise VariableError(_("The computer is not in the domain"))
        if self.Get('cl_remote_host') != '' and value == "off":
            raise VariableError(_("The computer is already in the domain %s")
                            %self.Get('cl_remote_host') + "\n" + 
                            _("Before joining the domain, "
                            "you need to remove it from the previous domain"))

    #def get(self):
    #    if self.Get('cl_remote_host') == '':
    #        return "on"
    #    else:
    #        return "off"

class VariableClClientMountSet(Variable):
    """
    Mount remote by configured domain information
    """
    type = "bool"
    value = "off"
    metavalue = "ON/OFF"
    opt = ["--mount"]

    def init(self):
        self.label = _("Only mount the domain resource")
        self.help = _("only mount the [remote] domain resource")

class VariableUrUserPw(Variable,LdapHelper):
    """
    Current user password
    """
    type = "need-onepassword"
    opt = ["--old-password"]
    metavalue = "OLDPASSWORD"
    value = ""
    untrusted = True

    def init(self):
        self.label = _("Current password")
        self.help = _("current user password")

    def checkUserPwdLDAP(self, server, userDN, password):
        """Check unix user password on server"""
        ldapInit = ldap.initialize("ldap://%s"%server)
        errMessage = ""
        try: 
            ldapInit.bind_s(userDN, password)
        except ldap.INVALID_CREDENTIALS:
            raise VariableError(_("Wrong password"))
        except ldap.LDAPError, e:
            errMessage = e[0]['desc']
            raise VariableError(errMessage)
        return True

    def check(self,value):
        if not value:
            raise VariableError(_("Empty password"))
        server = self.Get('cl_remote_host')
        ldapObj = self.getLdapUserObject()
        if ldapObj:
            usersDN = ldapObj.getUsersDN()
            userDN = ldapObj.addDN("uid=%s"%self.Get('ur_login'),
                                            usersDN)
            self.checkUserPwdLDAP(server,userDN,value)

class VariableUrUserNewPw(Variable):
    """
    New user password
    """
    type = "need-password"
    opt = ["--new-password"]
    metavalue = "NEWPASSWORD"
    value = ""
    untrusted = True

    def init(self):
        self.label = _("New password")
        self.help = _("new user password")

    def check(self,value):
        if not value:
            raise VariableError(_("Empty password"))
