import datetime
import simplejson as json

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.base import View
from ratelimit.decorators import ratelimit

from Model.models import Access_Log
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject
from Service.CommonService import CommonService
from Service.ModelService import ModelService
from Service.TemplateService import TemplateService
from Ansjer.config import SERVER_TYPE
from Object.RedisObject import RedisObject
'''
http://192.168.136.40:8077/accesslog?operation=queryByAdmin&token=test&page=1&line=5&order=-id
http://192.168.136.40:8077/accesslog?operation=truncateByAdmin&token=test
http://192.168.136.40:8077/accesslog?operation=searchByAdmin&token=test&page=1&line=10&content={"status":20}&order=-id



http://192.168.136.40:8077/accesslog/staticPath/?token=stest
'''



class AccessLog(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(AccessLog, self).dispatch(*args, **kwargs)

    def get(self, request):
        response = ResponseObject()
        request.encoding = 'utf-8'
        return self.validation(request.GET, response)

    def post(self, request):
        response = ResponseObject()
        request.encoding = 'utf-8'
        return self.validation(request.POST, response)

    def validation(self, request_dict, response):
        token = request_dict.get('token', None)
        tko = TokenObject(token)
        response.lang = tko.lang
        if tko.code != 0:
            return response.json(tko.code)
        userID = tko.userID
        operation = request_dict.get('operation', None)
        if not userID:
            return response.json(104)
        if not operation:
            return response.json(444, 'operation')
        if operation == 'queryByAdmin':
            return self.query_by_admin(request_dict, userID, response)
        elif operation == 'searchByAdmin':
            return self.search_by_admin(request_dict, userID, response)
        elif operation == 'truncateByAdmin':
            return self.truncate_by_admin(userID, response)

    def query_by_admin(self, request_dict, userID, response):
        page = int(request_dict.get('page', None))
        line = int(request_dict.get('line', None))
        order = request_dict.get('order', '-id')
        if order == '':
            order = '-id'
        if not page or not line:
            return response.json(444, 'page,line')
        own_perm = ModelService.check_perm(userID=userID, permID=30)
        if own_perm is not True:
            return response.json(404)
        if SERVER_TYPE == 'Ansjer.formal_settings':
            logKey = 'logger'
        else:
            logKey = 'test_logger'
        # 判断redis列表长度
        redisObj = RedisObject()
        data_list = redisObj.lrange(logKey, 0, -1)
        redisObj.del_data(key=logKey)
        ModelService.add_batch_log(data_list)
        qs = Access_Log.objects.all().order_by(order)
        if qs.exists():
            count = qs.count()
            res = qs[(page - 1) * line:page * line]
            send_json = CommonService.qs_to_dict(res)
            send_json['count'] = count
            return response.json(0, send_json)
        return response.json(0, {'datas': [], 'count': 0})

    # 清空日志表
    def truncate_by_admin(self, userID, response, ):
        check_perm = ModelService.check_perm(userID=userID, permID=10)
        if check_perm is True:
            from django.db import connection
            cursor = connection.cursor()
            sql = "TRUNCATE TABLE `access_log`"
            cursor.execute(sql)
            return response.json(0)
        else:
            return response.json(404)

    # 搜索日志(多条件)
    def search_by_admin(self, request_dict, userID, response):
        page = int(request_dict.get('page', None))
        line = int(request_dict.get('line', None))
        order = request_dict.get('order', '-id')
        content = request_dict.get('content', None)
        starttime = request_dict.get('starttime', None)
        endtime = request_dict.get('endtime', None)
        if SERVER_TYPE == 'Ansjer.formal_settings':
            logKey = 'logger'
        else:
            logKey = 'test_logger'
            # 判断redis列表长度
        redisObj = RedisObject()
        data_list = redisObj.lrange(logKey, 0, -1)
        redisObj.del_data(key=logKey)
        ModelService.add_batch_log(data_list)
        # qs = Access_Log.objects.all().order_by(order)
        if not page or not line:
            return response.json(444, 'page,line')
        check_perm = ModelService.check_perm(userID=userID, permID=20)
        if check_perm is not True:
            return response.json(404)
        try:
            content = json.loads(content)
            kwargs = {}
            for (k, v) in content.items():
                if v is not None and v != '':
                    if k == 'content':
                        kwargs[k + '__icontains'] = v
                    else:
                        kwargs[k] = v
            queryset = Access_Log.objects.filter(**kwargs).order_by(order)
        except Exception as e:
            return response.json(444)
        if starttime is not None and starttime != '' and endtime is not None and endtime != '':
            startt = datetime.datetime.fromtimestamp(int(starttime))
            starttime = startt.strftime("%Y-%m-%d %H:%M:%S.%f")
            endt = datetime.datetime.fromtimestamp(int(endtime))
            endtime = endt.strftime("%Y-%m-%d %H:%M:%S.%f")
            queryset = queryset.filter(time__range=(starttime, endtime))
        elif starttime is not None and starttime != '':
            startt = datetime.datetime.fromtimestamp(int(starttime))
            starttime = startt.strftime("%Y-%m-%d %H:%M:%S.%f")
            queryset = queryset.filter(time__gte=starttime)
        elif endtime is not None and endtime != '':
            endt = datetime.datetime.fromtimestamp(int(endtime))
            endtime = endt.strftime("%Y-%m-%d %H:%M:%S.%f")
            queryset = queryset.filter(time__lte=endtime)
        if queryset.exists():
            count = queryset.count()
            res = queryset[(page - 1) * line:page * line]
            send_json = CommonService.qs_to_dict(res)
            send_json['count'] = count
            return response.json(0, send_json)
        return response.json(0, {'datas': [], 'count': 0})


@ratelimit(key='ip', rate='3/m')
def statisticsPath(request):
    request.encoding = 'utf-8'
    if request.method == 'GET':
        token = request.GET.get('token', None)
    if request.method == 'POST':
        token = request.POST.get('token', None)
    response = ResponseObject()
    was_limited = getattr(request, 'limited', False)
    # 限制同一个ip该接口一分钟不能访问超过两次
    if was_limited is True:
        return response.json(5)
    tko = TokenObject(token)
    response.lang = tko.lang
    if tko.code != 0:
        return response.json(tko.code)
    userID = tko.userID
    own_perm = ModelService.check_perm(userID, 30)
    if own_perm is not True:
        return response.json(404)
    paths = TemplateService.log_api()
    datas = {}
    for path in paths:
        count = Access_Log.objects.filter(operation=path).count()
        datas[path] = count
    return response.json(0, {'datas': datas})


# 按季度删除访问日志
def deleteSn(request):
    response = ResponseObject()
    request.encoding = 'utf-8'
    if request.method == 'GET':
        request_dict = request.GET
    elif request.method == 'POST':
        request_dict = request.POST
    else:
        return response.json(104)
    token = request_dict.get('token', None)
    days = request_dict.get('days', None)
    if not days:
        return response.json(444, 'days')
    tko = TokenObject(token)
    response.lang = tko.lang
    if tko.code != 0:
        return response.json(tko.code)
    userID = tko.userID
    own_perm = ModelService.check_perm(userID, 10)
    if own_perm is not True:
        return response.json(404)
    for i in range(5):
        dltime = datetime.datetime.now() - datetime.timedelta(days=int(days))
        al_qs = Access_Log.objects.filter(time__gte=dltime)[0:10000]
        id_list = al_qs.values_list("id", flat=True)
        Access_Log.objects.filter(id__in=list(id_list)).delete()
    return response.json(0)
