"""
Acquisition module — Raspberry Shake device interaction.

Provides SSH-based datetime synchronisation and Earthworm waveform download.
"""

import logging
from datetime import datetime

import paramiko
from obspy import UTCDateTime
from obspy.clients.earthworm import Client

logger = logging.getLogger(__name__)


# ---------------------------------------------------------------------------
# Datetime synchronisation
# ---------------------------------------------------------------------------

def sync_datetime(
    host: str = "rs.local",
    username: str = "myshake",
    password: str = "shakeme",
) -> str:
    """Synchronise the Raspberry Shake clock with the current UTC time via SSH.

    Parameters
    ----------
    host : str
        Hostname or IP of the Raspberry Shake (default ``rs.local``).
    username : str
        SSH username.
    password : str
        SSH password.

    Returns
    -------
    str
        Combined stdout + stderr from the remote command.
    """
    date_now = datetime.utcnow().strftime("%d %b %Y %H:%M:%S")
    command = f'sudo -k date --set "{date_now}"'

    logger.info("Connecting to %s …", host)
    client = paramiko.client.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    try:
        client.connect(host, username=username, password=password)
        stdin, stdout, stderr = client.exec_command(command)
        stdin.write(password + "\n")
        stdin.flush()

        out = stdout.read().decode()
        err = stderr.read().decode()
        stdin.close()

        result = (out + "\n" + err).strip()
        logger.info("DateTime sync result: %s", result)
        return result
    finally:
        client.close()


# ---------------------------------------------------------------------------
# Earthworm data availability
# ---------------------------------------------------------------------------

def check_availability(
    host: str = "rs.local",
    port: int = 16032,
    network: str = "AM",
    station: str = "RCA8F",
    channel: str = "EHZ",
) -> list:
    """Check waveform availability on the Earthworm server.

    Returns
    -------
    list
        Availability information from the Earthworm server.
    """
    logger.info("Checking availability on %s:%d …", host, port)
    client = Client(host, port)
    response = client.get_availability(network, station, channel=channel)
    logger.info("Availability: %s", response)
    return response


# ---------------------------------------------------------------------------
# Waveform download
# ---------------------------------------------------------------------------

def download_waveforms(
    host: str = "rs.local",
    port: int = 16032,
    network: str = "AM",
    station: str = "RCA8F",
    location: str = "00",
    channel: str = "EH*",
    starttime: str = "",
    endtime: str = "",
    output_path: str = "output.mseed",
) -> "obspy.Stream":
    """Download waveforms from the Earthworm server and save to MiniSEED.

    Parameters
    ----------
    starttime, endtime : str
        ISO-8601 datetime strings (e.g. ``2023-01-11T08:10:00``).
    output_path : str
        Destination file path for the MiniSEED output.

    Returns
    -------
    obspy.Stream
        The downloaded stream object.
    """
    if not starttime or not endtime:
        raise ValueError("starttime and endtime must be provided.")

    logger.info("Downloading waveforms from %s:%d …", host, port)
    client = Client(host, port)
    ti = UTCDateTime(starttime)
    tf = UTCDateTime(endtime)

    st = client.get_waveforms(network, station, location, channel, ti, tf)
    logger.info("Downloaded %d trace(s): %s", len(st), st)

    st.write(output_path, format="MSEED")
    logger.info("Saved to %s", output_path)
    return st
