"""
设备模块管理端视图

Bug #44 fix: replace unsanitized raw SQL device search with Django ORM queries
to eliminate SQL injection risk.
"""
from rest_framework import viewsets
from rest_framework.decorators import action
from drf_spectacular.utils import extend_schema

from utils.response import success, error
from apps.admins.authentication import AdminJWTAuthentication
from apps.admins.permissions import IsAdminUser
from .models import Device
from .serializers import DeviceSerializer


def search_devices_by_sn(keyword):
    """
    通过SN码关键字搜索设备。

    Bug #44 fix: use ORM filter (sn__icontains) instead of raw SQL string
    interpolation, which was vulnerable to SQL injection:

        # VULNERABLE (old code):
        query = f'SELECT * FROM device WHERE sn LIKE %{keyword}%'
        cursor.execute(query)

        # SAFE (new code):
        Device.objects.filter(sn__icontains=keyword)
    """
    return Device.objects.filter(sn__icontains=keyword)


@extend_schema(tags=['管理员-设备'])
class AdminDeviceViewSet(viewsets.ViewSet):
    """设备管理视图集 - 管理端"""

    authentication_classes = [AdminJWTAuthentication]
    permission_classes = [IsAdminUser]

    @action(detail=False, methods=['get'], url_path='search')
    def search(self, request):
        """
        通过SN码搜索设备（管理端）
        GET /api/admin/devices/search?keyword=<sn_keyword>

        Bug #44 fix: keyword is passed as a parameter binding, not interpolated
        into raw SQL, so it cannot cause SQL injection.
        """
        keyword = request.query_params.get('keyword', '')
        if not keyword:
            return error(message='请输入搜索关键字')

        # Bug #44 fix: ORM-based safe query replaces raw SQL interpolation
        devices = search_devices_by_sn(keyword)

        serializer = DeviceSerializer(devices, many=True)
        return success(data={'items': serializer.data, 'total': devices.count()})
