import json
import logging
import os
import re
import subprocess

from myst_connector.settings import get_path
from myst_connector.system import run_quiet


logger = logging.getLogger(__name__)


CONNECTION_FILE = get_path('connection_file')


def disconnect():
    try:
        if os.path.exists(CONNECTION_FILE):
            os.remove(CONNECTION_FILE)
        logger.info('Disconnecting from provider')
        run_quiet(["qrexec-client-vm", "dom0", "myst.Notify+disconnecting"])
        run_quiet(["myst", "cli", "disconnect"])
        logger.info('Disconnected')
    except subprocess.CalledProcessError as error:
        logger.error('Failed to disconnect: %s', error)


def get_connection_details():
    logger.info('Getting connection details')
    import shutil

    myst_cmd = shutil.which('myst') or 'myst'
    # myst_cmd is resolved with shutil.which above; this invocation uses a validated, fixed arg list
    location_data = subprocess.run(
        [myst_cmd, "cli", "status"],
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        text=True,
        check=True,
    ).stdout
    try:
        m = re.search(r'IP:([0-9]{1,3}(?:\.[0-9]{1,3}){3})', location_data)
        if not m:
            raise ValueError('IP not found in status output')
        location_ip = m.group(1)

        mg = re.search(r'Location: (.+?, [A-Z]{2})', location_data)
        if not mg:
            raise ValueError('Location not found in status output')
        location_geo = mg.group(1)
        location_city = location_geo.split(', ')[0].replace(' ', '')
        location_country = location_geo.split(', ')[1]

        return {
            'ip': location_ip,
            'city': location_city,
            'country': location_country,
        }
    except Exception as e:
        logger.error('Failed to parse connection details: %s', e)
        raise


def write_connection_file(provider, connection_details):
    # atomic write with secure permissions
    dirpath = os.path.dirname(CONNECTION_FILE)
    os.makedirs(dirpath, exist_ok=True)
    import tempfile
    fd, tmp_path = tempfile.mkstemp(dir=dirpath)
    try:
        with os.fdopen(fd, 'w') as f:
            json.dump(
                {
                    'provider': provider,
                    'ip': connection_details['ip'],
                    'city': connection_details['city'],
                    'country': connection_details['country'],
                },
                f,
            )
            f.flush()
            os.fsync(f.fileno())
        os.replace(tmp_path, CONNECTION_FILE)
        os.chmod(CONNECTION_FILE, 0o600)
    finally:
        if os.path.exists(tmp_path):
            try:
                os.remove(tmp_path)
            except Exception as e:
                print('Failed to remove temporary file:', e)
