# -*- coding: utf-8 -*-

import configparser
import os
import subprocess

from . import templates
from .paths import AUTHORIZED_KEYS, INTERFACES_FILE, WG_CONF_FILE, WG_CONF_FILE_DISABLED

def get_authorized_keys():
    # Fetches content of root's authorized_files
    if not os.path.exists(AUTHORIZED_KEYS):
        return ''
    with open(AUTHORIZED_KEYS) as f:
        return f.read()

def set_authorized_keys(keys):
    # Saves content of root's authorized_files
    with open(AUTHORIZED_KEYS, 'w') as f:
        f.write(keys)
    # Enable or disable SSH service
    if keys.strip():
        subprocess.run(['/sbin/rc-update', 'add', 'sshd', 'boot'])
        subprocess.run(['/sbin/service', 'sshd', 'start'])
    else:
        subprocess.run(['/sbin/service', 'sshd', 'stop'])
        subprocess.run(['/sbin/rc-update', 'del', 'sshd', 'boot'])

def is_wireguard_running():
    # Returns status of wg0 interface (inferred from existence of its config file)
    return os.path.exists(WG_CONF_FILE)

def regenerate_wireguard_key():
    # Regenerates WireGuard key pair for wg0 interface
    was_running = is_wireguard_running()
    if was_running:
        stop_wireguard()
    privkey = subprocess.run(['wg', 'genkey'], stdout=subprocess.PIPE).stdout.strip().decode()
    with open(WG_CONF_FILE_DISABLED) as f:
        conf_lines = f.readlines()
    conf_lines[2] = 'PrivateKey = {}\n'.format(privkey)
    with open(WG_CONF_FILE_DISABLED, 'w') as f:
        f.writelines(conf_lines)
    if was_running:
        start_wireguard()
    return privkey

def get_wireguard_conf():
    # Returns dictionary with WireGuard wg0 interface VPN IP, public key, listen port and peer info
    result = {'running': is_wireguard_running()}
    # IP
    with open(INTERFACES_FILE) as f:
        for line in f.read().splitlines():
            if '172.17.255' in line:
                result['ip'] = line.split('.')[-1]
                break
    # Listen port and peers
    with open(WG_CONF_FILE if result['running'] else WG_CONF_FILE_DISABLED) as f:
        conf_lines = f.read().splitlines()
    result['port'] = conf_lines[1].split()[2]
    result['peers'] = '\n'.join(conf_lines[4:])
    # Public key
    privkey = conf_lines[2].split()[2]
    if privkey == 'None':
        privkey = regenerate_wireguard_key()
    p = subprocess.Popen(['wg', 'pubkey'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    result['pubkey'] = p.communicate(privkey.encode())[0].strip().decode()
    return result

def set_wireguard_conf(ip, port, peers):
    # Sets WireGuard wg0 interface VPN IP, listen port and peer info
    was_running = is_wireguard_running()
    if was_running:
        stop_wireguard()
    # IP
    interface_lines = []
    with open(INTERFACES_FILE) as f:
        for line in f.readlines():
            if '172.17.255' in line:
                line = '    address 172.17.255.{}\n'.format(ip)
            interface_lines.append(line)
    with open(INTERFACES_FILE, 'w') as f:
        f.writelines(interface_lines)
    # Recreate config (listen port and peers)
    with open(WG_CONF_FILE_DISABLED) as f:
        conf_lines = f.readlines()[:4]
    conf_lines[1] = 'ListenPort = {}\n'.format(port)
    with open(WG_CONF_FILE_DISABLED, 'w') as f:
        f.writelines(conf_lines)
        f.write(peers)
    if was_running:
        start_wireguard()

def start_wireguard():
    # Sets up WireGuard interface
    if not os.path.exists(WG_CONF_FILE):
        os.rename(WG_CONF_FILE_DISABLED, WG_CONF_FILE)
    else:
        subprocess.run(['ifdown', 'wg0'])
    subprocess.run(['ifup', 'wg0'])

def stop_wireguard():
    # Tears down WireGuard interface
    subprocess.run(['ifdown', 'wg0'])
    if os.path.exists(WG_CONF_FILE):
        os.rename(WG_CONF_FILE, WG_CONF_FILE_DISABLED)
