from .models import *

import os
import subprocess
import logging
import uuid
from django_q.tasks import async_task, result

log = logging.getLogger(__name__)


def configure_wireguard_server_on_host(wg_name, config):
    """
    - Create wireguard config (DB query -> string)
    - Submit config to cdist worker
    - Change config locally on worker / commit / shared
    """

    # Write config
    fname = f"/etc/wireguard/{wg_name}.conf"
    with open(fname, "w") as fd:
        fd.write(config)

    # Ensure the device exists
    subprocess.run(f"ip link show {wg_name} >/dev/null || sudo ip link add {{wg_name}} type wireguard",
                   shell=True, check=True)

    # Ensure the config is correct
    subprocess.run(f"sudo wg setconf {wg_name} {fname}",
                   shell=True, check=True)



def configure_wireguard_server_via_cdist(wireguardvpnpool):
    """
    - Create wireguard config (DB query -> string)
    - Submit config to cdist worker
    - Change config locally on worker / commit / shared

    """

    config = wireguardvpnpool.wireguard_config
    server = wireguardvpnpool.vpn_server_hostname

    log.info(f"Configuring VPN server {server} (async)")

    async_task(cdist_configure_wireguard_server,config, server).id


def cdist_configure_wireguard_server(config, server):
    """
    Create config and configure server.

    To be executed on the cdist worker.
    """

    dirname= "/home/app/.cdist/type/__ungleich_wireguard/files/"
    fname = os.path.join(dirname,server)

    log.info(f"Configuring VPN server {server} (on cdist host)")
    with open(fname, "w") as fd:
        fd.write(config)

    log.debug("git committing wireguard changes")
    subprocess.run(f"cd {dirname} && git pull && git add {server} && git commit -m 'Updating config for {server}' && git push",
                   shell=True, check=True)

    log.debug(f"Configuring VPN server {server} with cdist")
    subprocess.run(f"cdist config {server}", shell=True, check=True)

    # FIXME:
    # ensure logs are on the server
    # ensure exit codes are known
    return True
