import logging
import traceback

from django.core.exceptions import ObjectDoesNotExist
from rest_framework.generics import get_object_or_404

from inputs.constants import LICENSE_OPTION_EVENT_SOURCE_COUNT
from inputs.enums import LogInputType
from inputs.models import LogInput, LogInputArmaIF, LogInputEndpoint
from inputs.services.update_config import update_arma_config, update_endpoint_config
from license_info.tools import get_license_info

_log = logging.getLogger(__name__)


def get_allowed_input_count():
    """Calculate allowed input count from license"""
    try:
        info = get_license_info()
        license_restriction = info["options"][LICENSE_OPTION_EVENT_SOURCE_COUNT]

        if isinstance(license_restriction, str):
            license_restriction = int(license_restriction)

        allowed_count = license_restriction - LogInput.objects.all().count()

    except Exception:
        _log.error(traceback.format_exc())
        allowed_count = 0

    return allowed_count


def get_sensor(type_str):
    """ Parse sensor type and return found object or raise RuntimeError if
    bad type_str provided and LogInput.DoesNotExist if no such sensor found
    """

    sensor_type, pk = type_str.rsplit('_', 1)

    if sensor_type == "armaif":
        obj = LogInputArmaIF
    elif sensor_type == "endpoint":
        obj = LogInputEndpoint
    else:
        raise RuntimeError(f"Bad input type: {sensor_type}")
    try:
        return sensor_type, obj.objects.get(pk=pk).get_sensor()

    except ObjectDoesNotExist:
        raise LogInput.DoesNotExist()


def create_input(input_instance, port):
    if input_instance.type == LogInputType.ARMAIF:
        armaif_input = LogInputArmaIF(
            input=input_instance, port=port)
        armaif_input.save()
        update_arma_config(armaif_input)
    if input_instance.type == LogInputType.ENDPOINT:
        endpoint_input = LogInputEndpoint(
            input=input_instance, port=port)
        endpoint_input.save()
        update_endpoint_config(endpoint_input)
    input_instance.can_delete = True
    input_instance.save()


def update_input(input_instance, port):
    if port:
        if input_instance.type == LogInputType.ARMAIF:
            armaif_input = get_object_or_404(LogInputArmaIF, input=input_instance)
            armaif_input.port = port
            armaif_input.save()
            update_arma_config(armaif_input)
        if input_instance.type == LogInputType.ENDPOINT:
            endpoint_input = get_object_or_404(LogInputEndpoint, input=input_instance)
            endpoint_input.port = port
            endpoint_input.save()
            update_endpoint_config(endpoint_input)
    input_instance.can_delete = True
    input_instance.save()
