from django.contrib.auth.models import Group, User
from . import models
from rest_framework import serializers
from drf_writable_nested import WritableNestedModelSerializer

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['url', 'username', 'email', 'groups']

class device_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.device
        fields = ['id', 'device_type', 'brend', 'serial_model', 'proto', 'proto_interface']

class adc_params_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    device_model = serializers.CharField(max_length=100, write_only=True)
    device = device_Serializer(read_only=True)
    class Meta:
        model = models.adc_params
        fields = ['device_model', 'device', 'srate', 'points', 'n_channels', 'channel_ranges', 'n_triggers', 'averaging', 'trigger_channel', 'trig_direction', 'threshold', 'auto_measure_time', 'enabled']
        extra_kwargs = {
            'device': {'read_only': True}
        }

    # task: add create() for get device by serial_model
    def create(self, validated_data):
        # get device by serial_model
        device_model = validated_data.pop('device_model')
        device_instance = models.device.objects.get(serial_model=device_model)
        # create adc_params
        adc_params_instance = models.adc_params.objects.create(device=device_instance, **validated_data)
        return adc_params_instance

class sync_params_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    device_model = serializers.CharField(max_length=100, write_only=True)
    device = device_Serializer(read_only=True)
    class Meta:
        model = models.sync_params
        fields = ['device_model', 'device', 'file', 'port']
        extra_kwargs = {
            'device': {'read_only': True}
        }

    def create(self, validated_data):
        # get device by serial_model
        device_model = validated_data.pop('device_model')
        device_instance = models.device.objects.get(serial_model=device_model)
        # create sync_params with the device and other fields
        sync_params_instance = models.sync_params.objects.create(device=device_instance, **validated_data)
        return sync_params_instance

class sdr_params_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    device_model = serializers.CharField(max_length=100, write_only=True)
    device = device_Serializer(read_only=True)
    class Meta:
        model = models.sdr_params
        fields = ['device_model', 'device', 'srate', 'freq', 'ampl', 'gain', 'file']
        extra_kwargs = {
            'device': {'read_only': True}
        }

    def create(self, validated_data):
        # get device by serial_model
        device_model = validated_data.pop('device_model')
        device_instance = models.device.objects.get(serial_model=device_model)
        # create sdr_params
        sdr_params_instance = models.sdr_params.objects.create(device=device_instance, **validated_data)
        return sdr_params_instance

class gra_params_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    device_model = serializers.CharField(max_length=100, write_only=True)
    device = device_Serializer(read_only=True)
    class Meta:
        model = models.gra_params
        fields = ['device_model', 'device', 'ip', 'file', 'enabled']
        extra_kwargs = {
            'device': {'read_only': True}
        }

    def create(self, validated_data):
        # get device by serial_model
        device_model = validated_data.pop('device_model')
        device_instance = models.device.objects.get(serial_model=device_model)
        # create gra_params
        gra_params_instance = models.gra_params.objects.create(device=device_instance, **validated_data)
        return gra_params_instance

class measurement_info_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    #id = serializers.IntegerField()
    iadc = adc_params_Serializer()
    isync = sync_params_Serializer()
    isdr = sdr_params_Serializer()
    igrax = gra_params_Serializer()
    igray = gra_params_Serializer()
    igraz = gra_params_Serializer()
    class Meta:
        model = models.measurement_info
        fields = ['infostr', 'engine', 'time', 'iadc', 'isync', 'isdr', 'igrax', 'igray', 'igraz']

class measurement_info_lite_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.measurement_info
        fields = ['id', 'infostr', 'time']

class channel_data_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    channel_data = serializers.CharField(allow_blank=True, 
                                trim_whitespace=False,
                                required=False)
    #id = serializers.IntegerField()
    class Meta:
        model = models.channel_data
        fields = ['channel_num', 'channel_data']

class device_state_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.device_state
        fields = ['status', 'code']

class state_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    #id = serializers.IntegerField()
    adc = device_state_Serializer()
    sdr = device_state_Serializer()
    sync = device_state_Serializer()
    grax = device_state_Serializer()
    gray = device_state_Serializer()
    graz = device_state_Serializer()
    data_ready = serializers.BooleanField(default=False)
    class Meta:
        model = models.state
        fields = ['adc', 'sync', 'sdr', 'grax', 'gray', 'graz', 'code', 'status', 'data_ready']

class measurement_data_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    #id = serializers.IntegerField()
    channel_data = channel_data_Serializer(read_only=True, many=True)
    measurement_id = serializers.IntegerField(read_only=True, source="measurement.id")
    measurement_rate = serializers.IntegerField(read_only=True, source="measurement.info.iadc.srate")
    measurement_points = serializers.JSONField(read_only=True, source="measurement.info.iadc.points")
    #channel_data.id = id_data
    class Meta:
        model = models.measurement_data
        fields = ['measurement_id', 'data_num', 'averaging_num', 'channel_data', 'measurement_rate', 'measurement_points']

class measurement_post_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    #id = serializers.IntegerField()
    info = measurement_info_Serializer(write_only=True)
    infostr = serializers.CharField(read_only=True, source="info.infostr")
    #info.id = id
    #state.id = id
    class Meta:
        model = models.measurement
        fields = ['id', 'info', 'infostr']
        extra_kwargs = {
            'info': {'write_only': True}
        }

class measurement_Serializer(WritableNestedModelSerializer, serializers.HyperlinkedModelSerializer):
    #id = serializers.IntegerField()
    #info = measurement_info_Serializer()
    #info.id = id
    #data.id = id
    #state.id = id
    infostr = serializers.CharField(read_only=True, source="info.infostr")

    class Meta:
        model = models.measurement
        fields = ['id', 'infostr']