
from django.shortcuts import render
import psutil
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from django.conf import settings
import os
from rest_framework import serializers
from apps.monitor.serializers import DbbackupDeleteSerializer, AuditLogSerializer
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework.exceptions import NotFound
from rest_framework.mixins import ListModelMixin
from apps.monitor.filters import DrfLogFilterSet
from apps.monitor.models import DrfRequestLog, AuditLog

from apps.monitor.errors import LOG_NOT_FONED
from apps.monitor.services import ServerService, CeleryMonitor, RedisMonitor
from apps.utils.viewsets import CustomGenericViewSet

# Create your views here.


def index(request):
    return render(request, 'monitor/index.html')


def room(request, room_name):
    return render(request, 'monitor/room.html', {
        'room_name': room_name
    })


def video(request):
    return render(request, 'monitor/video.html')


class CeleryInfoView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, *args, **kwargs):
        """
        获取celery状态信息

        获取celery状态信息
        """
        return Response(CeleryMonitor.get_info())


class RedisInfoView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, *args, **kwargs):
        """
        获取redis状态信息

        获取redis状态信息
        """
        return Response(RedisMonitor.get_info())


class ServerInfoView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, *args, **kwargs):
        """
        获取服务器当前状态

        cpu/内存/硬盘
        """
        return Response(ServerService.get_full())


def get_file_list(file_path):
    dir_list = os.listdir(file_path)
    if not dir_list:
        return []
    else:
        # 注意，这里使用lambda表达式，将文件按照最后修改时间顺序升序排列
        # os.path.getmtime() 函数是获取文件最后修改时间
        # os.path.getctime() 函数是获取文件最后创建时间
        dir_list = sorted(dir_list, key=lambda x: os.path.getmtime(
            os.path.join(file_path, x)), reverse=True)
        # print(dir_list)
        return dir_list


class LogView(APIView):

    @swagger_auto_schema(manual_parameters=[
        openapi.Parameter('name', openapi.IN_QUERY,
                          description='日志文件名', type=openapi.TYPE_STRING)
    ])
    def get(self, request, *args, **kwargs):
        """
        查看最近的日志列表

        查看最近的日志列表
        """
        logs = []
        name = request.GET.get('name', None)
        # for root, dirs, files in os.walk(settings.LOG_PATH):
        #     files.reverse()
        for file in get_file_list(settings.LOG_PATH):
            if len(logs) > 50:
                break
            filepath = os.path.join(settings.LOG_PATH, file)
            if name:
                if name in filepath:
                    fsize = os.path.getsize(filepath)
                    if fsize:
                        logs.append({
                            "name": file,
                            "filepath": filepath,
                            "size": round(fsize/1024, 1)
                        })
            else:
                fsize = os.path.getsize(filepath)
                if fsize:
                    logs.append({
                        "name": file,
                        "filepath": filepath,
                        "size": round(fsize/1024, 1)
                    })
        return Response(logs)


class LogDetailView(APIView):

    def get(self, request, name):
        """
        查看日志详情

        查看日志详情
        """
        try:
            with open(os.path.join(settings.LOG_PATH, name)) as f:
                data = f.read()
            return Response(data)
        except Exception:
            raise NotFound(**LOG_NOT_FONED)


class DbBackupView(APIView):
    perms_map = {'get': '*', 'delete': 'dbback.delete'}

    @swagger_auto_schema(request_body=DbbackupDeleteSerializer, responses={200: {}})
    def delete(self, request):
        """
        删除备份

        删除备份
        """
        filepaths = request.data.get('filepaths', [])
        for i in filepaths:
            os.remove(i)
        return Response()

    @swagger_auto_schema(manual_parameters=[
        openapi.Parameter('name', openapi.IN_QUERY,
                          description='文件名', type=openapi.TYPE_STRING)
    ])
    def get(self, request, *args, **kwargs):
        """
        查看最近的备份列表

        查看最近的备份列表
        """
        items = []
        name = request.GET.get('name', None)
        # for root, dirs, files in os.walk(settings.LOG_PATH):
        #     files.reverse()
        backpath = settings.BACKUP_PATH + '/database'
        for file in get_file_list(backpath):
            if len(items) > 50:
                break
            filepath = os.path.join(backpath, file)
            if name:
                if name in filepath:
                    fsize = os.path.getsize(filepath)
                    if fsize:
                        items.append({
                            "name": file,
                            "filepath": filepath,
                            "size": round(fsize/1024/1024, 1)
                        })
            else:
                fsize = os.path.getsize(filepath)
                if fsize:
                    items.append({
                        "name": file,
                        "filepath": filepath,
                        "size": round(fsize/1024/1024, 1)
                    })
        return Response(items)


class DrfRequestLogSerializer(serializers.ModelSerializer):
    class Meta:
        model = DrfRequestLog
        fields = '__all__'


class DrfRequestLogViewSet(ListModelMixin, CustomGenericViewSet):
    """请求日志

    请求日志
    """
    perms_map = {'get': '*'}
    queryset = DrfRequestLog.objects.all()
    list_serializer_class = DrfRequestLogSerializer
    ordering = ['-requested_at']
    filterset_class = DrfLogFilterSet
    search_fields = ['path', 'view']


class AuditlogViewSet(ListModelMixin, CustomGenericViewSet):
    """审计日志

    审计日志
    """
    perms_map = {'get': '*'}
    queryset = AuditLog.objects.all()
    list_serializer_class = AuditLogSerializer
    ordering = ['-change_time']
    filterset_fields = ['change_user', 'model_name', 'action', 'instance_id']
    search_fields = ['model_name', 'action']
