# Copyright (c) 2026 동일비전(Dongil Vision Korea). All Rights Reserved.
"""core 공통 유틸리티 (순환 import 방지용 별도 모듈)"""

import sys as _sys

_IS_WIN32 = _sys.platform == 'win32'


def _fmt_debug_call(prefix, func_expr, args=(), kwargs=None, suffix=''):
    """Debug: function call을 멀티라인으로 포맷."""
    params = [repr(a) for a in args]
    if kwargs:
        params.extend(f"{k} = {repr(v)}" for k, v in kwargs.items())
    if not params:
        return f"{prefix}{func_expr}(){suffix}"
    pad = ' ' * 20 + '| '
    lines = [f"{prefix}{func_expr}("]
    for p in params:
        lines.append(f"{pad}  {p}")
    lines.append(f"{pad}){suffix}")
    return '\n'.join(lines)


def _sanitize_id(task_id: str) -> str:
    """task_id를 SHM 이름에 안전한 형식으로 변환."""
    return task_id.replace('.', '_').replace('-', '_')


def _build_chain(_chain, _tl_chain, caller):
    """RMI chain 병합 (순환 호출 감지용)."""
    if _chain:
        return _chain | {caller} if caller else _chain
    elif _tl_chain:
        return _tl_chain | {caller} if caller else _tl_chain
    else:
        return {caller} if caller else None


def _make_async_worker(call_fn, done, error, broker, caller):
    """async_call 공통 worker 생성."""
    def _worker():
        try:
            result = call_fn()
            if done and broker:
                broker.emit(done, result, caller or 'external')
        except Exception as e:
            if error and broker:
                broker.emit(error, str(e), caller or 'external')
            elif done and broker:
                broker.emit(done, None, caller or 'external')
    return _worker


def _check_port_in_use(port: int) -> bool:
    """포트 사용 여부 확인."""
    import socket
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        try:
            s.bind(('0.0.0.0', port))
            return False
        except OSError:
            return True


def _check_singleton(port: int) -> bool:
    """싱글턴 포트 체크. 사용 중이면 에러 출력 후 False 반환."""
    if _check_port_in_use(port):
        print(f"\n{'='*60}\n[ERROR] Port {port} in use\n{'='*60}\n")
        return False
    return True
