# -*- coding: utf-8 -*-
"""
    SwarmOps.utils.web
    ~~~~~~~~~~~~~~

    Common function for web.

    :copyright: (c) 2018 by staugur.
    :license: MIT, see LICENSE for more details.
"""

import json
from .tool import logger
from .jwt import JWTUtil, JWTException
from .aes_cbc import CBC
from libs.Base import CacheBase
from config import SSO
from functools import wraps
from flask import g, request, redirect, url_for, abort

jwt = JWTUtil()
cbc = CBC()


def get_referrer_url():
    """获取上一页地址"""
    if request.referrer and request.referrer.startswith(request.host_url) and request.endpoint and not "api." in request.endpoint:
        url = request.referrer
    else:
        url = None
    return url


def get_redirect_url(endpoint="front.index"):
    """获取重定向地址
    NextUrl: 引导重定向下一步地址
    ReturnUrl: 最终重定向地址
    以上两个不存在时,如果定义了非默认endpoint,则首先返回;否则返回referrer地址,不存在时返回endpoint默认主页
    """
    url = request.args.get('NextUrl') or request.args.get('ReturnUrl')
    if not url:
        if endpoint != "front.index":
            url = url_for(endpoint)
        else:
            url = get_referrer_url() or url_for(endpoint)
    return url


def set_ssoparam(ReturnUrl="/"):
    """生成sso请求参数,5min过期"""
    app_name = SSO.get("app_name")
    app_id = SSO.get("app_id")
    app_secret = SSO.get("app_secret")
    return cbc.encrypt(jwt.createJWT(payload=dict(app_name=app_name, app_id=app_id, app_secret=app_secret, ReturnUrl=ReturnUrl), expiredSeconds=300))


def set_sessionId(uid, seconds=43200, sid=None):
    """设置cookie"""
    payload = dict(uid=uid, sid=sid) if sid else dict(uid=uid)
    sessionId = jwt.createJWT(payload=payload, expiredSeconds=seconds)
    return cbc.encrypt(sessionId)


def verify_sessionId(cookie):
    """验证cookie"""
    if cookie:
        try:
            sessionId = cbc.decrypt(cookie)
        except Exception, e:
            logger.debug(e)
        else:
            try:
                success = jwt.verifyJWT(sessionId)
            except JWTException, e:
                logger.debug(e)
            else:
                # 验证token无误即设置登录态,所以确保解密、验证两处key切不可丢失,否则随意伪造!
                return success
    return False


def analysis_sessionId(cookie, ReturnType="dict"):
    """分析获取cookie中payload数据"""
    data = dict()
    if cookie:
        try:
            sessionId = cbc.decrypt(cookie)
        except Exception, e:
            logger.debug(e)
        else:
            try:
                success = jwt.verifyJWT(sessionId)
            except JWTException, e:
                logger.debug(e)
            else:
                if success:
                    # 验证token无误即设置登录态,所以确保解密、验证两处key切不可丢失,否则随意伪造!
                    data = jwt.analysisJWT(sessionId)["payload"]
    if ReturnType == "dict":
        return data
    else:
        return data.get("sid"), data.get("uid")


def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not g.signin:
            return redirect(url_for('sso.Login'))
        return f(*args, **kwargs)
    return decorated_function


def anonymous_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if g.signin:
            return redirect(get_redirect_url())
        return f(*args, **kwargs)
    return decorated_function


def set_userinfo(uid, userinfo, expire=None):
    """ 缓存uid用户信息5min """
    if uid and isinstance(userinfo, dict):
        key = "PublicCache:userinfo:{}".format(uid)
        source = get_userinfo(uid)
        source.update(userinfo)
        if source:
            cache = CacheBase()
            try:
                cache.set(key, json.dumps(source), expire)
            except Exception,e:
                logger.warn(e)
            else:
                return True
    return False


def get_userinfo(uid):
    """ 查看缓存中uid对应的用户信息 """
    if uid:
        key = "PublicCache:userinfo:{}".format(uid)
        cache = CacheBase()
        try:
            data = json.loads(cache.get(key))
        except:
            pass
        else:
            return data
    return dict()