#!/usr/bin/env python
#coding=utf-8

import requests
import json
from time import sleep
from imacinfo import ImacInfo
from logger.logrecord import LogRecord
from copy import deepcopy
import socket

class User:
    __loged       = False
    __userInfo    = None

    #----------------------------
    def getUserInfo(self):
        userInfo = deepcopy(User.__userInfo)
        return userInfo

    def setUsetInfo(self,userInfo):
        User.__userInfo = deepcopy(userInfo)

    #----------------------------
    def getUserLogedStatus(self):
       return User.__loged

    def setUserStatusLoged(self):
        User.__loged = True

    def setUserStatusLogout(self):
        User.__loged = False


class UserValidate(object):
    __terminalID   = None
    logouting = False
    def __init__(self,usrInfo,ip_port,httpStyle="http"):
        self.__userInfo     = usrInfo
        self.__url          = httpStyle + "://" + ip_port
        self.__localInfo    = ImacInfo()

        self.__user   = User()
        self.__user.setUsetInfo(self.__userInfo)
    # 登录
    def login(self):
        UserValidate.logouting = False
        try:

            LogRecord.instance().logger.debug("终端注册...")
            for i in range(3):
                res = self.__getTerminalID()  # 获取 TerminalId
                flag = res[0]
                if flag == False:
                    LogRecord.instance().logger.debug("终端注册失败...")
                    if i >= 2:
                        return res
                else:
                    UserValidate.__terminalID = res[1]
                    LogRecord.instance().logger.debug("终端注册成功...")
                    break
                del res

            LogRecord.instance().logger.debug("[info]: loginValidate ")
            res = self.__loginValidate()   # 用户验证
            flag = res[0]
            if flag == False:
                LogRecord.instance().logger.debug("登录验证通过失败")
                return res
            else:
                LogRecord.instance().logger.debug("登录验证通过")
            del res

            LogRecord.instance().logger.debug("[info]: session status search ")
            for i in range(10):
                res = self.sessionIsReady()  # 等 session回话 建立
                if res[0] == False:
                    LogRecord.instance().logger.debug("会话建立中....")
                    if i >=9:
                        self.logout()
                        LogRecord.instance().logger.debug("会话等待超时....")
                        return False,"session会话异常:%s " % str(res[1])
                    sleep(3)
                else:
                    LogRecord.instance().logger.debug("会话已建立")
                    break
                del res
            try:
                self.__user.setUsetInfo(self.__userInfo)
                self.__user.setUserStatusLoged()        # 设置登录标记
            except Exception as e:
                raise Exception("setUsetInfo err")

            LogRecord.instance().logger.debug("登录成功")
            return True,""

        except Exception as e:
            LogRecord.instance().logger.exception("登录异常")
            return  False, "登录异常"

    # 注销
    def logout(self):
        '''
            seccess : return [ True,    "" ]
            filed   : return [ False, "info"]
        '''
        UserValidate.logouting = True
        _userinfo = self.__user.getUserInfo()
        if _userinfo != None:
            self.__userInfo =_userinfo   # 更新 密码更改 用户信息,

        if UserValidate.__terminalID == None:
            return False,"ID_Invalid"

        try:
            url = "%s/api/users/logout/%s"% (self.__url,UserValidate.__terminalID)
            payload = {
                    "displayName"   :  "xxxx",      # 未定义
                    "inDomain"      :  "false",     # 未定义
                    "login"         :  self.__userInfo["userName"],
                    "password"      :  self.__userInfo["userPassword"],
            }
            headers = {'content-type':'application/json'}
            recv =  requests.post(url,data=json.dumps(payload), headers=headers,timeout=5)

            recv.raise_for_status()    # 如果recv.status_code状态码不是 200，就主动抛出异常

            # 判断 是否是 json类型
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                # print recv.text
                raise Exception(" content-type err %s ;not is  application/json" % recv.headers['content-type'])
            #print recv.text
            dict_tmp = recv.json()["result"]

            if dict_tmp == None:
                raise Exception("recv.json()[\"result\"] == None")


            if dict_tmp["status"] == "y":

                UserValidate.__terminalID = None
                return True,""
            else:
                return False,dict_tmp["info"]

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.exception("发送注销,网络连接错误")
            #print "链接错误"
            return False,"发送注销,网络连接错误"

        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.exception("发送注销,网络超时")
            return False,"发送注销,网络超时"

        except Exception as e:
            LogRecord.instance().logger.exception("logout Exception")
            return False,"注销异常"
        finally:
            pass

    # 终端注册
    def terminalRegist(self):
        res = self.__getTerminalID()
        if res[0] == False:
            LogRecord.instance().logger.error(res[1])
            pass
            # print "terminalRegist : ",  res[1]
        else:
            # print ""
            # #print "terminalRegist OK"
            # print ""
            pass

    # 获取 terminalID
    def __getTerminalID(self):
        '''
            seccess : return [ True,   terminalId_str ]
            filed   : return [ False, "info"]
        '''
        try:
            url = "%s/api/terminals" % str(self.__url)
            payload = {
                    "bindingIp"  : "false",
                    "boot_status": "0",
                    "dept"       : "1111",
                    "emp"        : "12313123",
                    "ip"         : self.__localInfo.get_ip_address(),
                    "mac_address": self.__localInfo.get_mac_address(),
                    "memSizeMB"  : self.__localInfo.getMemInfo(),
                    "name"       : self.__userInfo["userName"],
                    "status"     : "1",
                    "usage_cpu_percent" : "0",
                    "usage_disk_percent": "0",
                    "usage_mem_percent" : "0",
                    "usage_network_percent": "0"
            }

            headers = {'content-type':'application/json'}
            recv =  requests.post(url,data=json.dumps(payload), headers=headers,timeout=10)
            if recv.status_code != 200:
                # print "status_code : ",recv.status_code
                raise Exception("Http error %s" % recv.status_code)

            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                raise Exception(" content-type err %s ;not is  application/json" % recv.headers['content-type'])
            dict_tmp = recv.json()["result"]

            if dict_tmp == None:
                raise Exception("getterminalIDErr")

            status = dict_tmp["status"]               # 状态
            info   = dict_tmp["info"].encode('utf-8') # 信息

            if status != "y":                   # 上报失败
                return False, info

            # LogRecord.instance().logger.debug("terminal regist ID  : "+dict_tmp["result"]["id"])
            return True,dict_tmp["result"]["id"]  # 成功

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.exception("获取session状态异常,网络连接错误")
            return False,"网络不稳定或服务器地址验证失败"#"终端注册,网络连接错误"

        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.exception("获取session状态异常,网络超时")
            return False,"网络超时"#"终端注册,网络超时"

        except Exception as e:
            LogRecord.instance().logger.exception("get TerminalID ")
            return False,"终端上报异常"


    def __loginValidate(self): # 登录验证
        try:
            url = "%s/api/users/login/%s"% (self.__url,self.__localInfo.get_mac_address())
            # url = "%s/api/users/login/%s"% (self.__url,UserValidate.__terminalID)
            LogRecord.instance().logger.info("loginValidate : " +  url)
            payload = {
                    "displayName": "xxxx",
                    "inDomain"   : "false",
                    "login"      : self.__userInfo["userName"],
                    "password"   : self.__userInfo["userPassword"],

            }

            headers = {'content-type':'application/json'}

            recv =  requests.post(url,data=json.dumps(payload), headers=headers,timeout=10)
            recv.raise_for_status()    # 如果recv.status_code状态码不是 200，就主动抛出异常

            # 判断 是否是 json类型
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                # print recv.text
                raise Exception(" content-type err %s ;not is  application/json" % recv.headers['content-type'])

            # add by pbc for save userinformation -top
            try:
                from common import common_run
                common_run.user_information = recv.json()
            except:
                pass
            # add by pbc for save userinformation -end

            print "this is recv 0", recv.json()

            dict_tmp = recv.json()["result"]

            if dict_tmp == None:
                raise Exception("loginValidate result == None")

            status = dict_tmp["status"]
            # info   = dict_tmp["info"]
            info   = str(dict_tmp["info"].encode('utf-8'))

            if status == "y":
                LogRecord.instance().logger.info(",login success")
                return True,""
            else:
                LogRecord.instance().logger.warn("login warning,:" + str(info))
                return False,info,

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.exception("登录验证异常,网络连接错误" )
            #print "链接错误"
            return False,"登录验证,网络连接错误"

        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.exception("登录验证异常,网络超时")
            return False,"登录验证,网络超时"

        except Exception as e:
            LogRecord.instance().logger.exception("登录验证异常")

            return False,"登陆验证异常"



    def __getSessionInfo(self): # 获取session信息
        '''
            seccess : return [ True,   sessionInfo ]
            filed   : return [ False, "info"]
        '''
        try:
            # url = "%s/api/session/sessionInfo"% self.__url
            # # LogRecord.instance().logger.debug("getSessionInfo : " +  url)
            # payload = {
            #      		"login"     :self.__userInfo["userName"],
            #             "password"  :self.__userInfo["userPassword"],
            #             "inDomain"  :False
            # }
            localIP = self.__localInfo.get_ip_address()
            url = "%s/api/session/sessionStatus"% self.__url
            # LogRecord.instance().logger.debug("getSessionInfo : " +  url)
            # print url
            payload = {
                 		"userLogin"     :self.__userInfo["userName"],
                        "machineid"  :(self.__localInfo.get_mac_address()),
                        "clientIp"  :localIP
            }

            headers = {'content-type':'application/json'}
            recv =  requests.post(url,data=json.dumps(payload), headers=headers,timeout=10)

            if recv.status_code != 200:
                # print "status_code : ",recv.status_code
                raise Exception("Http error %s" % recv.status_code)

            # 判断 是否是 json类型
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                raise Exception(" content-type err %s ;not is  application/json" % recv.headers['content-type'])
            dict_tmp = recv.json()["result"]
            if dict_tmp == None:
                raise Exception("getSessionInfo result == None")

            status = dict_tmp["status"]
            info   = str(dict_tmp["info"].encode('utf-8'))

            if status != "y":
                return False,info

            sessionInfo = dict_tmp["result"]
            if sessionInfo == None:
                LogRecord.instance().logger.error("SessionStatus  : " +dict_tmp["info"])
                if UserValidate.logouting:
                    return False,'注销成功！'
                elif dict_tmp["info"].find("用户已在其他客户端登录") >= 0:
                    return False,dict_tmp["info"]#"session状态查询为None"
                else:
                    return False,"用户已被管理员注销！"

            # LogRecord.instance().logger.debug("SessionStatus  : [%s]" % sessionInfo["status"])
            return True, sessionInfo

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.error(str(url))
            LogRecord.instance().logger.exception("获取session状态异常,网络连接错误")
            return False,"获取会话状态,网络连接错误"

        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.error(str(url))
            LogRecord.instance().logger.exception("获取session状态异常,网络超时")
            return False,"获取会话状态,网络超时"

        except Exception as e:
            LogRecord.instance().logger.exception("获取session状态异常")
            return False, "获取会话状态异常"

    def sessionIsReady(self):  # 判断 session是否，是否Ready
        '''
            Ready       : return [ True,   sessionInfo ]
            not Ready   : return [ False, ""]
            Except     ： return [ False, "info"]
        '''
        try:
            res = self.__getSessionInfo()
            status = res[0]
            if status == False: # 如果失败，则返回 False 失败原因
                return res
            sessionInfo = res[1] # 如果成功
            #disconnected
            if sessionInfo["status"] == "ready" or \
                sessionInfo["status"] == "broken" or \
                sessionInfo["status"] == "logged" or \
                sessionInfo["status"] == "disconnected":  # ????
                return True, ""
            else:
                return False,sessionInfo["status"]

        except Exception as e:
            LogRecord.instance().logger.exception("获取session状态异常")
            return False,"获取session状态异常"

    # 查询注销
    def sessionIsLogout(self): # 查询sesion 是否被注销
        '''
            Logout       : return [ True,   sessionInfo ]
            not Logout   : return [ False, ""]
            Except     ： return [ False, "info"]
        '''
        try:
            res = self.__getSessionInfo()
            status = res[0]
            if status == False: # 如果失败，则返回 [ False,失败原因]
                #return res
                return True,res[1]         # 注销
                # return True,"网络异常"     # 注销

            sessionInfo = res[1] # 如果成功

            ####################################
            #----------- 平 时 查 询 应 该 这 样 弄-------------
            if sessionInfo["status"] == "destroying" or sessionInfo["status"] == "destroyed": #
                return  True,sessionInfo#"用户已经被注销"
            else:
                return  False,""
            #-------------------------
            ######################################


        except Exception as e:
            LogRecord.instance().logger.exception("sessionIsLogout :")
            return False,"sessionIsLogout err"


    # 注销命令 查询 专用接口
    def sessionIsLogout2(self): # 查询sesion 是否被注销
        '''
            Logout       : return [ True,   sessionInfo ]
            not Logout   : return [ False, ""]
            Except     ： return [ False, "info"]
        '''
        try:
            res = self.__getSessionInfo()
            status = res[0]
            if status == False: # 如果失败，则返回 [ False,失败原因]
                #return res
                return True,res[1]         # 注销
                # return True,"网络异常"     # 注销

            sessionInfo = res[1] # 如果成功

            ####################################
            #--- 注销 应 该 这 样 弄----
            if  sessionInfo["status"] == "destroyed": #
                return  True,"用户已经被注销"
            else:
                return  False,""
            ######################################


        except Exception as e:
            LogRecord.instance().logger.exception("sessionIsLogout ")
            return False,"sessionIsLogout err"


    # 更新会话状态为 loged
    def setSessionState_loged(self):  # 更新回话状态为louged
        try:
            res = self.__getSessionInfo()
            status = res[0]
            if status == False: # 如果失败，则返回 [ False,失败原因]
                return res

            sessionInfo = res[1]
            sessionInfo["status"] = "logged"
            self.__updateSessionState(sessionInfo)
        except Exception as e:
            LogRecord.instance().logger.exception("setSessionState_loged")
            return False , "setSessionState_loged"

    # 更新回话
    def __updateSessionState(self,sessionInfo): # 更新回话状态
        '''
            sessces       : return [ True,   sessionInfo ]
            Failed        : return [ False, "info"]
            Except       ： return [ False, "info"]
        '''
        try:
            url = "%s/api/session/update"% (self.__url)

            payload = sessionInfo
            headers = {'content-type':'application/json'}
            recv =  requests.post(url,data=json.dumps(payload), headers=headers,timeout=5)
            # recv.status_code()
            if recv.status_code != 200:
                # print "status_code : ",recv.status_code
                raise Exception("Http error %s" % recv.status_code)

            # 判断 是否是 json类型
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                # print recv.text
                raise Exception(" content-type err %s ;not is  application/json" % recv.headers['content-type'])
            dict_tmp = recv.json()["result"]

            if dict_tmp == None:
                LogRecord.instance().logger.error("updateSessionState result == None")
                return False,"updateSessionState result == None"

            LogRecord.instance().logger.debug("updateSessionState  : " + dict_tmp["status"])
            status  = dict_tmp["status"]
            info    = str(dict_tmp["info"].encode('utf-8'))
            if status == "y":
                return True,""
            else:
                return False,info

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.error(str(url))
            LogRecord.instance().logger.exception("updateSessionState")
            return False,"更新会话状态,网络连接错误"

        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.error(str(url))
            LogRecord.instance().logger.exception("updateSessionState ")
            return False,"更新回话状态,网络超时"

        except Exception as e:
            LogRecord.instance().logger.exception("updateSessionState")
            return  False,"更新回话状态失败"

    #
    # 获取密码等级
    def getPasswdLevel(self, ):

        url = "%s/api/users/getPwdRate" % self.__url
        try:
            recv = requests.get(url, timeout=4)
            recv.raise_for_status()  # 如果响应状态码不是 200，就主动抛出异常

            # 判断 是否是 json类型
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                print recv.headers['content-type']
                raise Exception(" content-type err %s ;not is  application/json" % recv.headers['content-type'])
            recvInfo = recv.json()
            if recvInfo == None:
                LogRecord.instance().logger.error("获取密码等级异常: Recv None")
                return False, "获取密码等级异常:  None"

            dict_tmp = recvInfo["result"]
            if dict_tmp == None:
                LogRecord.instance().logger.error("获取密码等级异常: result == None")
                return False, "获取密码等级异常: result == None"

            status = dict_tmp["status"]  # 状态
            info    = str(dict_tmp["info"].encode('utf-8'))

            if status != "y":
                infoMsg = "获取密码等级错误: %s" % info
                LogRecord.instance().logger.warn("getPasswdLevel : " +  str(infoMsg))
                return False, str(infoMsg)

            if dict_tmp["result"] == None:
                return False, "获取密码等级异常: result_result == None"

            if dict_tmp["result"]["configValue"] == None:
                return False, "获取密码等级异常: result_result_configValue == None"

            PasswdLevel = str(dict_tmp["result"]["configValue"])

            return True, PasswdLevel


        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.error(str(url))
            LogRecord.instance().logger.exception("getPasswdLevel ")
            return False,"获取密码等级,网络连接错误"

        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.error(str(url))
            LogRecord.instance().logger.exception("getPasswdLevel")
            return False,"获取密码等级,网络超时"

        except Exception as e:
            LogRecord.instance().logger.exception("getPasswdLevel")
            return False, "获取密码等级异常: %s "

    # -----------------------------------
    # 功能  ：  修改 密码
    # ----------------------------------
    def changeVMPasswd(self, oldPasswd, newPasswd):
        try:
            url = '%s/api/users/changePwd' % self.__url
            payload = {
                "login": self.__userInfo["userName"],
                "displayName": "null",
                "password": "null",
                "operateType": "null",
                "currPwd": oldPasswd,
                "newPwd": newPasswd,
                "inDomain": "true"
            }
            # print "------------------", json.dumps(payload)

            headers = {'content-type': 'application/json'}
            recv = requests.post(url, data=json.dumps(payload), headers=headers, timeout=5)
            recv.raise_for_status()  # 如果响应状态码不是 200，就主动抛出异常
            # 判断 是否是 json类型
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                print recv.headers['content-type']
                raise Exception(" content-type err %s ;not is  application/json" % recv.headers['content-type'])


            recvInfo = recv.json()
            if recvInfo == None:
                LogRecord.instance().logger.error("changed password : " +  "修改密码异常:recv None")
                return False, "修改密码异常:  None"
            dict_tmp = recvInfo["result"]
            if dict_tmp == None:
                LogRecord.instance().logger.error("changed password : " +  "修改密码异常: result == None")
                return False, "修改密码异常: result == None"


            status = dict_tmp["status"]  # 状态
            info    = str(dict_tmp["info"].encode('utf-8'))

            if status != "y":
                # infoMsg = "密码修改提示: %s" % info
                infoMsg = " %s" % info
                LogRecord.instance().logger.warn("changed password : " +  str(infoMsg))
                return False,str(infoMsg)

            self.__userInfo["userPassword"] = newPasswd # 更新用户名密码  ( 优化原子变量)
            self.__user.setUsetInfo(self.__userInfo)

            return True, "修改密码成功"


        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.exception("changed password")
            return False,"修改密码,网络连接错误"

        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.exception("changed password ")
            return False,"修改密码,网络超时"

        except Exception as e:
            LogRecord.instance().logger.exception("changed password : ")
            return False, "修改密码异常: %s "
