# -*- coding: utf-8 -*-
"""
Channel Management Permissions

This module defines permission classes and utilities for channel management
operations including channels, zones, EPG, jingles, and related functionality.
"""

from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.auth.decorators import permission_required
from django.core.exceptions import PermissionDenied
from django.utils.translation import gettext_lazy as _


class ChannelManagementPermissions:
    """
    Permission constants for channel management operations.
    
    These permissions control access to various channel management
    features and should be assigned to users or groups as needed.
    """
    
    # Channel permissions
    CAN_VIEW_CHANNELS = 'channels.view_channel'
    CAN_ADD_CHANNELS = 'channels.add_channel'
    CAN_CHANGE_CHANNELS = 'channels.change_channel'
    CAN_DELETE_CHANNELS = 'channels.delete_channel'
    
    # Channel Zone permissions
    CAN_VIEW_ZONES = 'channels.view_channelzone'
    CAN_ADD_ZONES = 'channels.add_channelzone'
    CAN_CHANGE_ZONES = 'channels.change_channelzone'
    CAN_DELETE_ZONES = 'channels.delete_channelzone'
    
    # Channel Codec permissions
    CAN_VIEW_CODECS = 'channels.view_channelcodec'
    CAN_ADD_CODECS = 'channels.add_channelcodec'
    CAN_CHANGE_CODECS = 'channels.change_channelcodec'
    CAN_DELETE_CODECS = 'channels.delete_channelcodec'
    
    # EPG Program permissions
    CAN_VIEW_EPG = 'channels.view_epgprogram'
    CAN_ADD_EPG = 'channels.add_epgprogram'
    CAN_CHANGE_EPG = 'channels.change_epgprogram'
    CAN_DELETE_EPG = 'channels.delete_epgprogram'
    
    # Jingle permissions
    CAN_VIEW_JINGLES = 'channels.view_jingle'
    CAN_ADD_JINGLES = 'channels.add_jingle'
    CAN_CHANGE_JINGLES = 'channels.change_jingle'
    CAN_DELETE_JINGLES = 'channels.delete_jingle'
    
    # Schedule permissions
    CAN_VIEW_SCHEDULES = 'channels.view_channelschedule'
    CAN_ADD_SCHEDULES = 'channels.add_channelschedule'
    CAN_CHANGE_SCHEDULES = 'channels.change_channelschedule'
    CAN_DELETE_SCHEDULES = 'channels.delete_channelschedule'
    
    # Advanced permissions
    CAN_MANAGE_VPN_CONFIGS = 'channels.change_channelzonerelation'
    CAN_VIEW_JINGLE_DETECTIONS = 'channels.view_jingledetection'
    CAN_CONFIRM_JINGLE_DETECTIONS = 'channels.change_jingledetection'
    CAN_PERFORM_HEALTH_CHECKS = 'channels.view_channel'
    CAN_VIEW_CHANNEL_STATS = 'channels.view_channel'


class ChannelPermissionRequiredMixin(PermissionRequiredMixin):
    """
    Custom permission mixin for channel management views.
    
    Extends Django's PermissionRequiredMixin to provide better
    error handling and permission checking for channel operations.
    """
    
    def handle_no_permission(self):
        """
        Handle cases where user doesn't have required permissions.
        
        Returns:
            HttpResponse: Appropriate response for permission denial
        """
        if self.request.user.is_authenticated:
            raise PermissionDenied(
                _("You don't have permission to access this resource.")
            )
        return super().handle_no_permission()
    
    def has_permission(self):
        """
        Check if user has all required permissions.
        
        Returns:
            bool: True if user has all required permissions
        """
        perms = self.get_permission_required()
        return self.request.user.has_perms(perms)


# Permission checking functions
def has_channel_management_permission(user, permission):
    """
    Check if user has specific channel management permission.
    
    Args:
        user: Django User instance
        permission (str): Permission string to check
        
    Returns:
        bool: True if user has the permission
    """
    return user.has_perm(permission)


def has_channel_zone_permission(user, action='view'):
    """
    Check if user has channel zone permissions.
    
    Args:
        user: Django User instance
        action (str): Action to check ('view', 'add', 'change', 'delete')
        
    Returns:
        bool: True if user has the permission
    """
    permission_map = {
        'view': ChannelManagementPermissions.CAN_VIEW_ZONES,
        'add': ChannelManagementPermissions.CAN_ADD_ZONES,
        'change': ChannelManagementPermissions.CAN_CHANGE_ZONES,
        'delete': ChannelManagementPermissions.CAN_DELETE_ZONES,
    }
    
    permission = permission_map.get(action)
    if not permission:
        return False
        
    return user.has_perm(permission)


def has_epg_management_permission(user, action='view'):
    """
    Check if user has EPG management permissions.
    
    Args:
        user: Django User instance
        action (str): Action to check ('view', 'add', 'change', 'delete')
        
    Returns:
        bool: True if user has the permission
    """
    permission_map = {
        'view': ChannelManagementPermissions.CAN_VIEW_EPG,
        'add': ChannelManagementPermissions.CAN_ADD_EPG,
        'change': ChannelManagementPermissions.CAN_CHANGE_EPG,
        'delete': ChannelManagementPermissions.CAN_DELETE_EPG,
    }
    
    permission = permission_map.get(action)
    if not permission:
        return False
        
    return user.has_perm(permission)


def has_jingle_management_permission(user, action='view'):
    """
    Check if user has jingle management permissions.
    
    Args:
        user: Django User instance
        action (str): Action to check ('view', 'add', 'change', 'delete')
        
    Returns:
        bool: True if user has the permission
    """
    permission_map = {
        'view': ChannelManagementPermissions.CAN_VIEW_JINGLES,
        'add': ChannelManagementPermissions.CAN_ADD_JINGLES,
        'change': ChannelManagementPermissions.CAN_CHANGE_JINGLES,
        'delete': ChannelManagementPermissions.CAN_DELETE_JINGLES,
    }
    
    permission = permission_map.get(action)
    if not permission:
        return False
        
    return user.has_perm(permission)


# Decorator functions for function-based views
require_channel_view_permission = permission_required(
    ChannelManagementPermissions.CAN_VIEW_CHANNELS,
    raise_exception=True
)

require_channel_add_permission = permission_required(
    ChannelManagementPermissions.CAN_ADD_CHANNELS,
    raise_exception=True
)

require_channel_change_permission = permission_required(
    ChannelManagementPermissions.CAN_CHANGE_CHANNELS,
    raise_exception=True
)

require_channel_delete_permission = permission_required(
    ChannelManagementPermissions.CAN_DELETE_CHANNELS,
    raise_exception=True
)

require_epg_view_permission = permission_required(
    ChannelManagementPermissions.CAN_VIEW_EPG,
    raise_exception=True
)

require_epg_add_permission = permission_required(
    ChannelManagementPermissions.CAN_ADD_EPG,
    raise_exception=True
)

require_jingle_view_permission = permission_required(
    ChannelManagementPermissions.CAN_VIEW_JINGLES,
    raise_exception=True
)

require_jingle_add_permission = permission_required(
    ChannelManagementPermissions.CAN_ADD_JINGLES,
    raise_exception=True
)