from django.db import transaction

from .models    import *
from .selectors import *
from .tasks     import *
from django_q.tasks import async_task, result

@transaction.atomic
def create_wireguard_vpn(owner, public_key, network_mask):
    # Check if the user has a membership.
    #------------------------------------
    # If yes, user is eligible for API access and 2 VPNs
    # If user already has 2 VPNs, we deduct from the credit
    # If deduction is higher than the allowed credit, we fail


    #
    # Check if the user has suitable balance
    # Create order
    #
    return create_wireguard_vpn_tech(owner, public_key, network_mask)

@transaction.atomic
def create_wireguard_vpn_tech(owner, public_key, network_mask):
    pool = get_suitable_pools(network_mask)[0]
    count = pool.wireguardvpn_set.count()

    # Try re-using previously used networks first
    try:
        free_lease = WireGuardVPNFreeLeases.objects.get(vpnpool=pool)

        vpn = WireGuardVPN.objects.create(owner=owner,
                                           vpnpool=pool,
                                           pool_index=free_lease.pool_index,
                                           wireguard_public_key=public_key)

        free_lease.delete()

    except WireGuardVPNFreeLeases.DoesNotExist:
        # First object
        if count == 0:
            vpn = WireGuardVPN.objects.create(owner=owner,
                                              vpnpool=pool,
                                              pool_index=0,
                                              wireguard_public_key=public_key)

        else: # Select last network and try +1 it
            last_net = WireGuardVPN.objects.filter(vpnpool=pool).order_by('pool_index').last()

            next_index = last_net.pool_index + 1

            if next_index <= pool.max_pool_index:
                vpn = WireGuardVPN.objects.create(owner=owner,
                                                   vpnpool=pool,
                                                   pool_index=next_index,
                                                   wireguard_public_key=public_key)


    config = pool.wireguard_config
    server = pool.vpn_server_hostname
    wg_name = pool.wg_name

    async_task(configure_wireguard_server_on_host, (wg_name, config), queue=server)

    return vpn
