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

import dns.resolver
import requests
import socket
import subprocess

from . import paths

def compile_url(domain, port, proto='https'):
    port = '' if (proto in (None, 'https') and port == '443') or (proto == 'http' and port == '80') else f':{port}'
    return f'{proto}://{domain}{port}' if proto else f'{domain}{port}'

def get_local_ip(version=None):
    # Return first routable IPv4/6 address of the VM (container host)
    # If version is not given, try getting IPv4, if that fails, try getting IPv6, if that fails too, fall back to 127.0.0.1
    if not version:
        return get_local_ip(4) or get_local_ip(6) or '127.0.0.1'
    try:
        output = subprocess.run(['/sbin/ip', 'route', 'get', '1' if version == 4 else '2003::'], check=True, stdout=subprocess.PIPE).stdout.decode().split()
        # Get field right after 'src'
        return output[output.index('src')+1]
    except (subprocess.CalledProcessError, ValueError, IndexError):
        return None

def get_external_ip(version):
    # Return external IPv4/6 address via remote service
    family = socket.AF_INET if version == 4 else socket.AF_INET6
    allowed_gai_family = requests.packages.urllib3.util.connection.allowed_gai_family
    try:
        requests.packages.urllib3.util.connection.allowed_gai_family = lambda: family
        return requests.get(paths.MYIP_URL, timeout=5).text
    except requests.RequestException:
        return None
    finally:
        requests.packages.urllib3.util.connection.allowed_gai_family = allowed_gai_family

resolver = dns.resolver.Resolver()
resolver.timeout = 3
resolver.lifetime = 3
resolver.nameservers = ['1.1.1.1', '1.0.0.1', '2606:4700:4700::1111', '2606:4700:4700::1001']

def resolve_ip(domain, query_type):
    # Resolve domain name using Cloudflare Public DNS
    try:
        return resolver.query(domain, query_type)[0].address
    except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
        return None

def ping_url(url):
    return requests.get(paths.PING_URL, params={'url': url}, timeout=5).text == 'vm-pong'
