#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import Ice, sys, time, os, select
from collections import deque
Ice.loadSlice('Murmur.ice')
import Murmur

ICE_HOST = '127.0.0.1'
ICE_PORT = 6502
ICE_SECRET = 'Kangen@1234'
FLOOR_TIMEOUT = 15
CHECK_INTERVAL = 0.2
LOG_DIR = 'logs'

if not os.path.exists(LOG_DIR):
    os.makedirs(LOG_DIR)

class FloorControl:
    def __init__(self, server):
        self.server = server
        self.current_holder = None
        self.floor_acquire_time = None
        self.queue = deque()

    def log(self, msg):
        print(msg)
        with open(os.path.join(LOG_DIR, "floor_control.log"), "a") as f:
            f.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} {msg}\n")

    def add_to_queue(self, user):
        if user.session not in [u.session for u in self.queue]:
            self.queue.append(user)
            self.log(f"[QUEUE] {user.name} masuk antrean.")

    def release_floor(self):
        if self.current_holder:
            self.log(f"[INFO] Floor dilepas dari {self.current_holder.name}")
            self.unmute_all()
            self.current_holder = None
            self.floor_acquire_time = None

    def acquire_floor(self):
        if self.current_holder is None and self.queue:
            user = self.queue.popleft()
            self.current_holder = user
            self.floor_acquire_time = time.time()
            self.log(f"[INFO] Floor diberikan kepada {user.name}")
            self.mute_others(user)

    def mute_others(self, user):
        for client in self.server.getClients().values():
            state = self.server.getState(client.session)
            state.mute = client.session != user.session
            self.server.setState(client.session, state)

    def unmute_all(self):
        for client in self.server.getClients().values():
            state = self.server.getState(client.session)
            state.mute = False
            self.server.setState(client.session, state)

    def check_timeout(self):
        if self.current_holder:
            elapsed = time.time() - self.floor_acquire_time
            if elapsed > FLOOR_TIMEOUT:
                self.log(f"[TIMEOUT] Floor timeout {self.current_holder.name}")
                self.release_floor()

def main():
    ice_args = ["--Ice.ImplicitContext=Shared"]
    ic = Ice.initialize(ice_args)
    proxy = ic.stringToProxy(f"Meta:tcp -h {ICE_HOST} -p {ICE_PORT},secret={ICE_SECRET}")
    meta = Murmur.MetaPrx.checkedCast(proxy)
    
    if not meta:
        print("Tidak bisa terhubung ke Murmur Ice.")
        sys.exit(1)
    
    servers = meta.getAllServers()
    if not servers:
        print("Tidak ada server aktif.")
        sys.exit(1)
    server = servers[0]
    print(f"[INFO] Terhubung ke server: {server.getName()}")

    floor_control = FloorControl(server)

    try:
        while True:
            clients = server.getClients()
            for client in clients.values():
                if client.prioritySpeaker:
                    floor_control.add_to_queue(client)

            floor_control.check_timeout()
            floor_control.acquire_floor()

            # Command manual (opsional)
            if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
                command = sys.stdin.readline().strip().lower()
                if command == "release":
                    floor_control.release_floor()
                elif command == "queue":
                    print("[QUEUE] Saat ini antrean:", [u.name for u in floor_control.queue])
                elif command == "exit":
                    print("[INFO] Bot dihentikan.")
                    break

            time.sleep(CHECK_INTERVAL)

    except KeyboardInterrupt:
        print("[INFO] Bot dihentikan manual.")

if __name__ == "__main__":
    main()
