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

import time
import struct
import zmq
import threading


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(2):
            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(2):
            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(2):
            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__':
    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()

