#!/usr/bin/env python3
# combined_pc_publisher.py – runs horizontal (X), vertical (Y), depth (Z) publishers, plus filename publisher

import time
import struct
#import zmq
import threading
from datetime import datetime
import paho.mqtt.client as mqtt
import struct
import sys
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.connect("192.168.1.89", 1883)

RUN_DURATION = 2 * 60   # 30 minutes

def publisher_1():
    while True:
        buf = bytearray()
        for i in range(10):
            x = 1.0 + i * 0.5
            y = 0.0
            z = 0.0
            buf += struct.pack('<fffBBH', x, y, z, 100, 1, 1)
        
        client.publish("lidar/scan", buf)   # ← topic name needed!
        print("Publisher 1 sent X points")
        time.sleep(1.0)

def publisher_2():
    while True:
        buf = bytearray()
        for i in range(10):
            x = 1.0 + i * 0.5
            y = 0.0
            z = 0.0
            buf += struct.pack('<fffBBH', x, y, z, 100, 1, 1)
        
        client.publish("lidar/car2/scan", buf)   # ← topic name needed!
        print("Publisher 2 sent Y points")
        time.sleep(1.0)


def publisher_3():
    while True:
        buf = bytearray()
        for i in range(10):
            x = 1.0 + i * 0.5
            y = 0.0
            z = 0.0
            buf += struct.pack('<fffBBH', x, y, z, 100, 1, 1)
        
        client.publish("lidar/car3/scan", buf)   # ← topic name needed!
        print("Publisher 3 sent Z points")
        time.sleep(1.0)



'''
def publisher_1():  # Horizontal X-variation → tcp://*:5556
    ctx = zmq.Context()
    sock = ctx.socket(zmq.PUB)
    sock.bind("tcp://*:5556")
    time.sleep(1)
    while True:
        buf = bytearray()
        for i in range(1000000):
            x = 1.0 + i * 0.5
            y = 0.0
            z = 0.0
            buf += struct.pack('<fffBBH', x, y, z, 100, 1, 1)
        sock.send(buf)
        print("Publisher 1 ▶ sent horizontal points")
        time.sleep(0.5)


def publisher_2():  # Vertical Y-variation → tcp://*:5557
    ctx = zmq.Context()
    sock = ctx.socket(zmq.PUB)
    sock.bind("tcp://*:5557")
    time.sleep(1)
    while True:
        buf = bytearray()
        for i in range(1000000):
            x = 0.0
            y = 2.0 + i * 0.5
            z = 0.0
            buf += struct.pack('<fffBBH', x, y, z, 150, 2, 2)
        sock.send(buf)
        print("Publisher 2 ▶ sent vertical points")
        time.sleep(0.5)


def publisher_3():  # Depth Z-variation → tcp://*:5558
    ctx = zmq.Context()
    sock = ctx.socket(zmq.PUB)
    sock.bind("tcp://*:5558")
    time.sleep(1)
    while True:
        buf = bytearray()
        for i in range(1000000):
            x = 0.0
            y = 0.0
            z = 3.0 + i * 0.5
            buf += struct.pack('<fffBBH', x, y, z, 200, 3, 3)
        sock.send(buf)
        print("Publisher 3 ▶ sent depth points")
        time.sleep(0.5)


def filename_publisher():  # Publishes filenames → tcp://*:5559
    ctx = zmq.Context()
    sock = ctx.socket(zmq.PUB)
    sock.bind("tcp://*:5559")
    time.sleep(0.2)

    toggle = True  # Switch between normal and malicious names
    while True:
        filename = "out.txt" if toggle else "out.txt; whoami"
        sock.send_string(filename)
        print(f"Published filename: {filename}")
        toggle = not toggle
        time.sleep(0.5)
'''

if __name__ == '__main__':

    start_time = time.time()  # ← start timer
    threads = [
        threading.Thread(target=publisher_1, name="pub1"),
        threading.Thread(target=publisher_2, name="pub2"),
        threading.Thread(target=publisher_3, name="pub3"),
   #     threading.Thread(target=filename_publisher, name="fname-pub"),
    ]
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    # No t.join() needed!
    '''
    while True:
        elapsed = time.time() - start_time
        if elapsed >= RUN_DURATION:
            print(f"[{datetime.now():%Y-%m-%d %H:%M:%S}] 30 mins reached — stopping!")
            sys.exit(0)  # ← kills all daemon threads automatically
        time.sleep(1)'''
