# -*- coding: UTF-8 -*-
import time
from frame.base import jsonUtil
from com.huawei.ism.exception import IsmException
from java.lang import Exception as JException

class RestConnection(object):
    AUTHENTICATE_URI = r"https://%s:%s/deviceManager/rest/%s/sessions"
    REST_BASE_URI = r"https://%s:%s/deviceManager/rest/%s/"
    RE_CONNECTION_TIMES = 3
    PROXY_OF_SVP_CONNECTION_TIMES = 2
    REST_PORT_DEFAULT = 8088
    REST_SCOPE_DEFAULT = "0"
    REST_CAN_NOT_CONNECT_CODE = 1073949185 #与设备通信异常，请检查网络连接或设备状态是否正常
    REST_INVALID_CODE = ["-401"]
    _instance = None
    _rest = None
       
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(RestConnection, cls).__new__(cls, *args, **kwargs)
        return cls._instance
    
    def __init__(self, connectorFactory, ip, devSN, restPort = REST_PORT_DEFAULT):
        self.connectorFactory = connectorFactory
        self.ip = ip
        self.restPort = restPort
        self.devSN = devSN
        self.baseUri = self.REST_BASE_URI % (self.getUrlIp(ip), str(restPort), str(devSN))
        self.loginUri = self.AUTHENTICATE_URI % (self.getUrlIp(ip), str(restPort), str(devSN))
        self._rest = None
        
    def create(self, user, pawd, scope = REST_SCOPE_DEFAULT):
        """
        @summary: 创建rest连接
        @param user: 用户名
        @param pawd: 密码
        @param scope: 用户类型
        @return: 
            True:建立成功
            False:建立失败   
        """
        successFlag = False
        exception = ""
        reConnectionTimes = 0
        while self._rest is None and reConnectionTimes < \
                RestConnection.RE_CONNECTION_TIMES + RestConnection.PROXY_OF_SVP_CONNECTION_TIMES:
            try:
                restConnector = self.connectorFactory.createRestConnector(self.loginUri, user, pawd, scope)
                restConnection = restConnector.getConnection()
                if reConnectionTimes % 2 == 0:
                    content = restConnection.login().getContent()
                else:
                    login_result = restConnection.loginSvpProxy()
                    if login_result:
                        content = login_result.getContent()
                    else:
                        reConnectionTimes += 1
                        continue
                responseInfo = jsonUtil.jsonStr2Dict(content)
                data = responseInfo["data"]
                iBaseToken = data.get("iBaseToken", None)
                if iBaseToken is not None:
                    successFlag = True
                    self._rest = restConnection
                    break
                reConnectionTimes += 1 
            except (Exception, JException) as e:
                exception = e
                reConnectionTimes += 1
                
        del pawd
        if not successFlag:
            raise IsmException(self.REST_CAN_NOT_CONNECT_CODE, unicode(exception))
        
        return successFlag
    
    def close(self):
        if self._rest is not None:
            try:
                self._rest.closeSession()
            except:
                return
            finally:
                self.Logout()
                self._rest = None
        return
    
    def getRestConnection(self, user, pawd, scope):
        try:
            if self._rest is None or not self.checkConnetionNormal():
                self.Logout()
                self._rest = None
                self.create(user, pawd, scope)
        except (Exception,JException),e:
            raise IsmException(self.REST_CAN_NOT_CONNECT_CODE, unicode(e))
        
        return self._rest
    
    def getBaseUri(self):
        return self.baseUri
    
    def getRest(self):
        return self._rest

    def checkConnetionNormal(self):
        uri = self.baseUri + "system/"
        paramsStr = ""
        try:
            records = jsonUtil.jsonStr2Dict(self._rest.execGet(uri, paramsStr).getContent())
            error = records["error"]
            errorCode = str(error.get("code", "")).strip()
            if errorCode in self.REST_INVALID_CODE:
                return False
            return True
        except:
            return False
    
    def getUrlIp(self,ip):
        if ":" in str(ip):
            return "[%s]" % str(ip)
        return str(ip)
    
    def Logout(self):
        '''
        @summary: Logout current connection from OM
        '''
        paramsStr = ""
        try:
            if self._rest is not None:
                self._rest.execDelete(self.loginUri, paramsStr)
        except:
            return
