import socket
import os
import time
import subprocess

# Configuration
HOST = "localhost"
PORT = 12345
INPUT_FILE = "wav/input.wav"
OUTPUT_FILE = "wav/received.wav"


def encrypt_data(data):
    return data  # Replace with your encryption protocol


def decrypt_data(data):
    return data  # Replace with your decryption protocol


def run_protocol(send_mode=True):
    """Connect to the simulator and send/receive data."""
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((HOST, PORT))
    print(f"Connected to simulator at {HOST}:{PORT}")

    if send_mode:
        # Sender mode: Encode audio with toast
        os.system(f"toast -p -l {INPUT_FILE}")  # Creates input.wav.gsm
        input_gsm_file = f"{INPUT_FILE}.gsm"
        if not os.path.exists(input_gsm_file):
            print(f"Error: {input_gsm_file} not created")
            sock.close()
            return
        with open(input_gsm_file, "rb") as f:
            voice_data = f.read()

        encrypted_data = encrypt_data(voice_data)
        sock.send(encrypted_data)
        print(f"Sent {len(encrypted_data)} bytes")
        os.remove(input_gsm_file)  # Clean up
    else:
        # Receiver mode: Wait for and receive data
        print("Waiting for data from sender...")
        received_data = b""
        sock.settimeout(5.0)
        try:
            while True:
                print("Calling recv()...")
                data = sock.recv(1024)
                print(f"Received {len(data)} bytes")
                if not data:
                    print("Connection closed by sender or simulator")
                    break
                received_data += data
        except socket.timeout:
            print("Timed out waiting for data")

        if received_data:
            with open("received.gsm", "wb") as f:
                f.write(decrypt_data(received_data))
            print(f"Wrote {len(received_data)} bytes to received.gsm")
            # Decode with untoast, then convert to WAV with sox
            result = subprocess.run(["untoast", "received.gsm"], capture_output=True, text=True)
            print(f"untoast return code: {result.returncode}")
            print(f"untoast stderr: {result.stderr}")
            if result.returncode == 0:
                if os.path.exists("received"):
                    # Convert raw PCM to WAV (8 kHz, mono, 16-bit)
                    subprocess.run(["sox", "-t", "raw", "-r", "8000", "-e", "signed", "-b", "16", "-c", "1", "received",
                                    OUTPUT_FILE])
                    os.remove("received")
                    print(f"Received and saved {len(received_data)} bytes to {OUTPUT_FILE}")
                else:
                    print("Error: 'received' file not created by untoast")
            else:
                print(f"untoast failed: {result.stderr}")
        else:
            print("No data received from simulator")

    sock.close()


if __name__ == "__main__":
    mode = input("Enter 'send' to send data or 'receive' to receive data: ").strip().lower()
    run_protocol(send_mode=(mode == "send"))