# Generated by Django 4.0.6 on 2024-01-29 22:32

from django.db import migrations, models
from jsonschema import Draft202012Validator


def create_rf_configurations(apps, schema_editor):
    StationType = apps.get_model('base', 'StationType')
    StationConfigurationSchema = apps.get_model('base', 'StationConfigurationSchema')

    station_type = StationType.objects.get_or_create(name='RF')[0]

    basic_schema = {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "$id": "https://network.satnogs.org/static/rf_basic_configuration_schema",
        "title": "SatNOGS Basic RF Station Configuration",
        "description": "The basic configuration schema for a SatNOGS RF Station",
        "type": "object",
        "properties": {
            "Location Configuration": {
                "description": "Configuration related to Station's Location",
                "type": "object",
                "properties": {
                    "satnogs_station_elev": {
                        "title": "Station Elevation",
                        "description": "Elevation of the station location in meters. Higher precision of this value increases accuracy of Doppler correction while lower precision increases station location privacy.",
                        "type": "integer",
                        "minimum": -500
                    },
                    "satnogs_station_lat": {
                        "title": "Station Latitude",
                        "description": "Latitude of the station location in decimal degrees. Higher precision of this value increases accuracy of Doppler correction while lower precision increases station location privacy.",
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                    },
                    "satnogs_station_lon": {
                        "title": "Station Longitude",
                        "description": "Longitude of the station location decimal degrees. Higher precision of this value increases accuracy of Doppler correction while lower precision increases station location privacy.",
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                    }
                },
                "required": ["satnogs_station_elev", "satnogs_station_lat", "satnogs_station_lon"],
                "additionalProperties": False
            },
            "Soapy Configuration": {
                "description": "Configuration to set Soapy parameters",
                "type": "object",
                "properties": {
                    "satnogs_soapy_rx_device": {
                        "title": "Soapy RX Device",
                        "description": "Soapy RX Device",
                        "type": "string",
                        "maxLength": 40,
                        "default": "driver=rtlsdr"
                    },
                    "satnogs_antenna": {
                        "title": "Soapy RX Device Antenna",
                        "description": "SoapySDR device antenna to use for RX. Valid antennas for attached devices can be queried using SoapySDRUtil --probe.",
                        "type": "string",
                        "maxLength": 40,
                        "default": "RX"
                    },
                    "satnogs_rx_samp_rate": {
                        "title": "Soapy RX Sampling Rate",
                        "description": "SoapySDR device sample rate in samples per second(sps). Valid sample rates for attached devices can be queried using SoapySDRUtil --probe.",
                        "type": "integer",
                        "minimum": 0,
                        "default": 2048000
                    }
                },
                "required": [
                    "satnogs_soapy_rx_device",
                    "satnogs_antenna",
                    "satnogs_rx_samp_rate",
                ],
                "additionalProperties": False
            }
        },
        "required": ["Location Configuration", "Soapy Configuration"],
        "additionalProperties": False
    }

    try:
        basic_station_configuration_schema = StationConfigurationSchema.objects.get(
            name='Basic Configuration', station_type=station_type
        )
        basic_station_configuration_schema.schema = basic_schema
    except StationConfigurationSchema.DoesNotExist:
        basic_station_configuration_schema = StationConfigurationSchema(
            name='Basic Configuration', station_type=station_type, schema=basic_schema
        )

    basic_station_configuration_schema.save()

    unregistered_schema = {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "$id": "https://network.satnogs.org/static/rf_basic_configuration_schema",
        "title": "SatNOGS Unregistered RF Station Configuration",
        "description": "The unregistered configuration schema for a SatNOGS RF Station",
        "type": "object",
        "properties": {
            "Location Configuration": {
                "description": "Configuration related to Station's Location",
                "type": "object",
                "properties": {
                    "satnogs_station_elev": {
                        "title": "Station Elevation",
                        "description": "Elevation of the station location in meters. Higher precision of this value increases accuracy of Doppler correction while lower precision increases station location privacy.",
                        "type": "integer",
                        "minimum": -500
                    },
                    "satnogs_station_lat": {
                        "title": "Station Latitude",
                        "description": "Latitude of the station location in decimal degrees. Higher precision of this value increases accuracy of Doppler correction while lower precision increases station location privacy.",
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                    },
                    "satnogs_station_lon": {
                        "title": "Station Longitude",
                        "description": "Longitude of the station location decimal degrees. Higher precision of this value increases accuracy of Doppler correction while lower precision increases station location privacy.",
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                    }
                },
                "required": ["satnogs_station_elev", "satnogs_station_lat", "satnogs_station_lon"],
                "additionalProperties": False
            },
        },
        "required": ["Location Configuration"],
        "additionalProperties": False
    }

    try:
        unregistered_station_configuration_schema = StationConfigurationSchema.objects.get(
            name='Unregistered Configuration', station_type=station_type
        )
        unregistered_station_configuration_schema.schema = unregistered_schema
    except StationConfigurationSchema.DoesNotExist:
        unregistered_station_configuration_schema = StationConfigurationSchema(
            name='Unregistered Configuration',
            station_type=station_type,
            schema=unregistered_schema
        )

    unregistered_station_configuration_schema.save()


def reverse_create_rf_configurations(apps, schema_editor):
    StationConfigurationSchema = apps.get_model('base', 'StationConfigurationSchema')
    StationConfigurationSchema.objects.filter(name='Basic Configuration').delete()
    StationConfigurationSchema.objects.filter(name='Unregistered Configuration').delete()


def migrate_data_of_stations(apps, schema_editor):
    Station = apps.get_model('base', 'Station')
    StationConfiguration = apps.get_model('base', 'StationConfiguration')
    StationConfigurationSchema = apps.get_model('base', 'StationConfigurationSchema')

    basic_configuration_schema = StationConfigurationSchema.objects.get(name='Basic Configuration')
    unregistered_configuration_schema = StationConfigurationSchema.objects.get(
        name='Unregistered Configuration'
    )
    stations = Station.objects.all()

    for station in stations:
        name = 'Unregistered'
        configuration_json = {
            "Location Configuration": {
                "satnogs_station_elev": station.alt or 0,
                "satnogs_station_lat": station.lat or 0,
                "satnogs_station_lon": station.lng or 0
            }
        }
        configuration_schema = unregistered_configuration_schema

        if station.client_id:
            try:
                current_conf = StationConfiguration.objects.get(station=station, active=True)
            except StationConfiguration.DoesNotExist:
                current_conf = None

            name = 'Basic'
            configuration_json = {
                "Location Configuration": {
                    "satnogs_station_elev": station.alt or 0,
                    "satnogs_station_lat": station.lat or 0,
                    "satnogs_station_lon": station.lng or 0
                },
                "Soapy Configuration": {
                    "satnogs_soapy_rx_device": current_conf.configuration['Soapy Configuration']
                    ['soapy_rx_device'] if current_conf else 'driver=rtlsdr',
                    "satnogs_antenna": current_conf.configuration['Soapy Configuration']
                    ['soapy_rx_antenna'] if current_conf else 'RX',
                    "satnogs_rx_samp_rate": current_conf.configuration['Soapy Configuration']
                    ['soapy_rx_samp_rate'] if current_conf else 2048000,
                }
            }
            configuration_schema = basic_configuration_schema

        try:
            Draft202012Validator(configuration_schema.schema).validate(configuration_json)
        except:
            continue

        StationConfiguration.objects.filter(station=station).delete()

        station_configuration = StationConfiguration(
            name=name,
            station=station,
            schema=configuration_schema,
            configuration=configuration_json,
            active=True
        )
        station_configuration.save()


def reverse_migrate_data_of_stations(apps, schema_editor):
    StationConfiguration = apps.get_model('base', 'StationConfiguration')
    StationConfiguration.objects.all().delete()


class Migration(migrations.Migration):

    dependencies = [
        ('base', '0113_alter_station_options'),
    ]

    operations = [
        migrations.RunPython(create_rf_configurations, reverse_create_rf_configurations),
        migrations.RunPython(migrate_data_of_stations, reverse_migrate_data_of_stations),
    ]
