import sys
import struct
import ctypes
import threading
import win32pipe
import win32file


pipe_name = r"\\.\pipe\botext"
pipe_access = win32pipe.PIPE_ACCESS_DUPLEX
pipe_type =win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT | win32pipe.PIPE_READMODE_MESSAGE
pipe_mode = win32pipe.PIPE_UNLIMITED_INSTANCES
max_instances = 65536
out_buffer_size = 65536
default_time_out = 0
security_attributes = None


pipe = win32pipe.CreateNamedPipe(
    pipe_name,
    pipe_access,
    pipe_type,
    pipe_mode,
    max_instances,
    out_buffer_size,
    default_time_out,
    security_attributes,
)


def write_data(data):
    msglen = len(data)
    msglen_bytes = struct.pack("=I", msglen)
    sys.stdout.buffer.write(msglen_bytes)
    sys.stdout.buffer.write(data.encode())
    sys.stdout.buffer.flush()


def read_thread_func():
    while True:
        raw_msglen = sys.stdin.buffer.read(4)
        if not raw_msglen:
            sys.exit(0)
        msglen = struct.unpack("=I", raw_msglen)[0]

        # Read the message data
        data = sys.stdin.buffer.read(msglen)
        ctypes.windll.user32.MessageBoxW(0, data.decode(), "BotExt", 0)
        write_data('{"msg": "bridge"}')


def namepipe_server(pipe):
    try:
        while True:
            win32pipe.ConnectNamedPipe(pipe, None)
            _, data = win32file.ReadFile(pipe, 4096)
            if data == b"close":
                sys.exit(0)
            print(data)
            write_data('{"msg": "client"}')
            # ctypes.windll.user32.MessageBoxW(0, "hi", "BotExt", 0)
            win32pipe.DisconnectNamedPipe(pipe)
    except Exception as e:
        win32pipe.DisconnectNamedPipe(pipe)
    finally:
        win32file.CloseHandle(pipe)


def namepipe_server_forver(pipe):
    while True:
        namepipe_server(pipe)


if __name__ == "__main__":
    thread = threading.Thread(target=read_thread_func)
    thread2 = threading.Thread(target=namepipe_server_forver, args=(pipe,))
    thread.daemon = True
    thread2.daemon = True
    thread.start()
    thread2.start()
    thread.join()
    thread2.join()
