#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
@AUTHOR: ASJRD019
@NAME: AnsjerFormal
@software: PyCharm
@DATE: 2020/3/18 9:38
@Version: python3.6
@MODIFY DECORD:ansjer dev
@file: AppSetController.py
@Contact: pzb3076@163.com
"""
import requests
import base64
from Ansjer.config import SERVER_TYPE
from Model.models import ApplicationModel, Device_User, GrantCodeModel
from django.views.generic.base import View
from Object.RedisObject import RedisObject
from Object.TokenObject import TokenObject
from Service.ModelService import ModelService
from Service.CommonService import CommonService
from django.http import JsonResponse, HttpResponseRedirect
from django.contrib import auth
import time,json
from Object.ResponseObject import ResponseObject
# http://192.168.136.39:8000/login/oauth/authorize
# http://192.168.136.39:8000/application/query
class AuthView(View):
    def get(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation', None)
        try:
            content_range = request.META['HTTP_AUTHORIZATION']
            print(content_range)
        except Exception as e:
            content_range = ''
        return self.validation(request.GET, operation, content_range)

    def post(self, request, *args, **kwargs):
        request.encoding = 'utf-8'

        operation = kwargs.get('operation', None)
        try:
            content_range = request.META['HTTP_AUTHORIZATION']
            print(content_range)
        except Exception as e:
            content_range = ''
        return self.validation(request.POST, operation, content_range)

    def validation(self, request_dict, operation, content_range):
        response = ResponseObject()
        if operation == 'authorize':
            return self.do_authorize(request_dict, response,content_range)
        elif operation == 'access_token':
            return self.do_token(request_dict, response, content_range)
        elif operation == 'user':
            return self.do_user(request_dict, response,content_range)
        else:
            return response.json(414)

    def do_authorize(self,request_dict, response, content_range):
        state = request_dict.get("state", '')
        client_id = request_dict.get("client_id", '')
        response_type = request_dict.get("response_type", '')
        scope = request_dict.get("scope", '')
        app_id = request_dict.get("appBundleId", '')
        redirect_uri = request_dict.get("redirect_uri", '')
        token = request_dict.get('token', None)
        # print("client_id", client_id)
        # print("state", state)
        # print("response_type", response_type)
        # print("scope", scope)
        # print("app_id", app_id)
        # print("redirect_uri", redirect_uri)
        tko = TokenObject(token)
        if tko.code == 0:
            userID = tko.userID
            nowTime = int(time.time())
            user_qs = GrantCodeModel.objects.filter(userID__userID=userID)
            code = CommonService.encrypt_data(randomlength=32)
            application = ApplicationModel.objects.filter(client_id=client_id)
            if application.exists():
                print(application.exists())
            else:
                return response.json(10005)
            if redirect_uri == '':
                pass
            else:
                if application[0].redirect_uri != redirect_uri:
                    return response.json(10006)
            if user_qs.exists():
                print('在修改')
                user_qs.update(code=code, app_id=app_id, update_time=nowTime, expire_time=nowTime + 3600)
            else:
                print('在创建')
                try:
                    grantcode = GrantCodeModel(
                        userID=Device_User.objects.get(userID=userID),
                        application=ApplicationModel.objects.get(client_id=client_id),
                        code=code,
                        app_id=app_id,
                        expire_time=nowTime + 3600,
                        add_time=nowTime,
                        update_time=nowTime)
                    grantcode.save()
                except Exception as e:
                    print(repr(e))
                    return response.json(178)
            if state == '':
                state = 'cHpi'
            redirect_uri = application[0].redirect_uri + '?code=' + code + '&state=' + state
            if application[0].skip_auth:
                return HttpResponseRedirect(redirect_uri)
            return response.json(0, {'url': redirect_uri})
        else:
            return response.json(tko.code)

    # 增加对code和client_id，client_secret的校验代码，返回access_token和refresh_token
    def do_token(self,request_dict, response, content_range):
        code = request_dict.get("code", None)
        print('code:')
        print(code)
        str = content_range
        # str = 'Basic cHpiMTIzNDU2Nzg6cHpiMTIzNDU2Nzg='
        if str != '':
            str = str[6:]
            str = base64.b64decode(str)
            print(str)
            str = bytes.decode(str)
            print(type(str))
            str_all = str.split(":", 1)
            client_id = str_all[0]
            client_secret = str_all[1]
            eq = ApplicationModel.objects.filter(client_secret=client_secret, client_id=client_id)
            if eq.exists():
                access_token = code
                refresh_token = CommonService.encrypt_data(randomlength=32)
                res_json = {
                    "access_token": access_token,
                    "token_type": "bearer",
                    "expires_in": 3600,
                    "refresh_token": refresh_token,
                    'scope': 'cHpi'
                }
                print(res_json)
                return JsonResponse(res_json)
            else:
                return response.json(10001)
        else:
            return response.json(10002)

    def do_user(self, request_dict, response,content_range):
        str = content_range
        # str = 'Bearer iBO4WssoK60eF4o6zm1e0fcHe2wRlRm1'
        if str != '':
            token = str[7:]
            code_qs = GrantCodeModel.objects.filter(code=token)
            if code_qs.exists():
                print(code_qs[0].userID_id)
                user_qs = Device_User.objects.filter(userID=code_qs[0].userID_id)
                # print(CommonService.qs_to_dict(user_qs)['datas'][0]['fields'])
                res_json = CommonService.qs_to_dict(user_qs)['datas'][0]['fields']
                res_json.pop('password')
                res_json.update(user_id=CommonService.qs_to_dict(user_qs)['datas'][0]['pk'])
                print(res_json)
                return JsonResponse(res_json)
            else:
                print('没有找到数据')
                return response.json(10003)
        else:
            return response.json(10004)


class ApplicationView(View):
    def get(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation', None)
        return self.validation(request.GET, operation)

    def post(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation', None)
        return self.validation(request.POST, operation)

    def validation(self, request_dict, operation):
        response = ResponseObject()
        token = request_dict.get('token', None)
        tko = TokenObject(token)
        if tko.code == 0:
            userID = tko.userID
            if operation == 'query':
                return self.query(request_dict, userID, response)
            elif operation == 'add':
                return self.add(request_dict, userID, response)
            elif operation == 'update':
                return self.update(request_dict, userID, response)
            elif operation == 'delete':
                return self.delete(request_dict, userID, response)
            else:
                return response.json(414)
        else:
            return response.json(tko.code)
    def add(self, request_dict, userID, response):
        own_perm = ModelService.check_perm(userID=userID, permID=40)
        if own_perm is not True:
            return response.json(404)
        # http://192.168.136.39:8000/application/add?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySUQiOiIxMzgwMDEzODAwMSIsImxhbmciOiJjbiIsInVzZXIiOiIxMzgwMDEzODAwMSIsIm1fY29kZSI6IjEyMzQxMzI0MzIxNCIsImV4cCI6MTU4NzYxNjQ0NX0.BIwq - eWDcTnqLBTxqpi7BgJoU9TeIHC5Ibc2LUUJPls&name=pzb&client_id=pzb12345&client_secret=pzb12345678&client_type=confidential&grant_type=authorization_code&redirect_uri=https://www.zositech.cn&skip_auth=1
        nowTime = int(time.time())
        name = request_dict.get('name', None)
        client_id = request_dict.get('client_id', None)
        client_secret = request_dict.get('client_secret', None)
        client_type = request_dict.get('client_type', None)
        grant_type = request_dict.get('grant_type', None)
        redirect_uri = request_dict.get('redirect_uri', None)
        skip_auth = request_dict.get('skip_auth', None)
        try:
            ApplicationModel.objects.create(add_time=nowTime, update_time=nowTime, client_id=client_id, name=name, client_secret=client_secret,
                                           client_type=client_type,redirect_uri=redirect_uri,skip_auth=skip_auth,grant_type=grant_type)
            return response.json(0)
        except Exception as e:
            return response.json(178,repr(e))

    def query(self, request_dict, userID, response):
        own_perm = ModelService.check_perm(userID, 20)
        if own_perm is True:
            page = int(request_dict.get('page', 0))
            line = int(request_dict.get('line', 0))
            if page == 0:
                page=1
            if line == 0:
                line=10
            qs = ApplicationModel.objects.all()

            if qs.exists():
                count = qs.count()
                res = qs[(page - 1) * line:page * line]
                send_json = CommonService.qs_to_dict(res)
                for k, v in enumerate(send_json["datas"]):
                    print(send_json['datas'][k]['pk'])
                    gc = GrantCodeModel.objects.filter(application = send_json['datas'][k]['pk'])
                    send_json["datas"][k]['fields']['count_num'] = gc.count()
                send_json['count'] = count

                return response.json(0, send_json)
            else:
                return response.json(0, {'datas': [], 'count': 0})
        else:
            return response.json(404)

    # 管理员的编辑
    def update(self, request_dict, userID, response):
        own_perm = ModelService.check_perm(userID=userID, permID=50)
        if own_perm is not True:
            return response.json(404)

        deviceContent = request_dict.get('content', None)
        id = request_dict.get('id', None)
        if not deviceContent or not id:
            return response.json(444, 'content,id')
        try:
            timestamp = int(time.time())
            deviceData = json.loads(deviceContent)
            uid_set = ApplicationModel.objects.filter(id=id)
            if uid_set.exists():
                uid_set.update(update_time=timestamp, **deviceData)
                return response.json(0,{"update_time":timestamp})
            else:
                return response.json(173)
        except Exception:
            return response.json(177)

    def delete(self, request_dict, userID, response):
        own_perm = ModelService.check_perm(userID=userID, permID=10)
        if own_perm is not True:
            return response.json(404)
        id = request_dict.get('id', None)
        uid_set = ApplicationModel.objects.filter(id=id)
        if uid_set.exists():
            uid_set.delete()
            return response.json(0)
        else:
            return response.json(173)


class GrantCodeView(View):
    def get(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation', None)
        return self.validation(request.GET, operation)

    def post(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation', None)
        return self.validation(request.POST, operation)

    def validation(self, request_dict, operation):
        response = ResponseObject()
        token = request_dict.get('token', None)
        tko = TokenObject(token)
        if tko.code == 0:
            userID = tko.userID
            if operation == 'query':
                return self.query(request_dict, userID, response)
            elif operation == 'delete':
                return self.delete(request_dict, userID, response)
            else:
                return response.json(414)
        else:
            return response.json(tko.code)


    def query(self, request_dict, userID, response):
        own_perm = ModelService.check_perm(userID, 20)
        if own_perm is True:
            page = int(request_dict.get('page', 0))
            line = int(request_dict.get('line', 0))
            if page == 0:
                page=1
            if line == 0:
                line=10
            gc = GrantCodeModel.objects.filter()
            if gc.exists():
                count = gc.count()
                res = gc[(page - 1) * line:page * line].values('id', 'userID', 'userID__username', 'userID__userEmail', 'userID__NickName', 'userID__language', 'userID__phone', 'code', 'app_id', 'application', 'add_time', 'update_time')
                send_json = CommonService.qs_to_list(res)
                return response.json(0, {'datas': send_json, 'count': count})
            else:
                return response.json(0, {'datas': [], 'count': 0})
        else:
            return response.json(404)


    def delete(self, request_dict, userID, response):
        own_perm = ModelService.check_perm(userID=userID, permID=10)
        if own_perm is not True:
            return response.json(404)
        id = request_dict.get('id', None)
        uid_set = GrantCodeModel.objects.filter(id=id)
        if uid_set.exists():
            uid_set.delete()
            return response.json(0)
        else:
            return response.json(173)

