"""
Kill switch.

state/orders_disabled 파일 존재 시 모든 진입점에서 거부.
LLM 에이전트(클로·레이) 세션에서 호출 시 즉시 차단 (OPENCLAW_AGENT 환경변수).

모든 매매 진입점 함수 첫 줄에서 guard_or_raise() 호출이 강제이다.
"""

from __future__ import annotations

import json
import os
import sys
from datetime import datetime, timezone, timedelta
from pathlib import Path

WORKSPACE_ROOT = Path(__file__).resolve().parent.parent.parent
LIMITS_FILE = Path(__file__).resolve().parent / 'limits.json'

KST = timezone(timedelta(hours=9))


class SidecarBlocked(RuntimeError):
    pass


def _limits() -> dict:
    return json.loads(LIMITS_FILE.read_text(encoding='utf-8'))


def _kill_switch_path() -> Path:
    return WORKSPACE_ROOT / _limits()['kill_switch_file']


def _agent_env_blocked() -> bool:
    var = _limits().get('telegram', {}).get('block_when_agent_env_set')
    return bool(var and os.getenv(var))


def is_disabled() -> bool:
    return _kill_switch_path().exists()


def guard_or_raise() -> None:
    if _agent_env_blocked():
        raise SidecarBlocked('LLM agent session cannot invoke order module (OPENCLAW_AGENT env set)')
    if is_disabled():
        raise SidecarBlocked('Order module is disabled (sidecar ON)')


def disable(reason: str = 'manual') -> Path:
    p = _kill_switch_path()
    p.parent.mkdir(parents=True, exist_ok=True)
    p.write_text(
        json.dumps({'disabled_at': datetime.now(KST).isoformat(), 'reason': reason}, ensure_ascii=False, indent=2),
        encoding='utf-8',
    )
    try:
        os.chmod(p, 0o600)
    except OSError:
        pass
    return p


def enable() -> bool:
    p = _kill_switch_path()
    if not p.exists():
        return False
    p.unlink()
    return True


def status() -> dict:
    p = _kill_switch_path()
    if not p.exists():
        return {'disabled': False, 'path': str(p), 'agent_env_blocked': _agent_env_blocked()}
    try:
        meta = json.loads(p.read_text(encoding='utf-8'))
    except (OSError, ValueError):
        meta = {}
    meta.update({'disabled': True, 'path': str(p), 'agent_env_blocked': _agent_env_blocked()})
    return meta


def _cli(argv: list[str]) -> int:
    if not argv or argv[0] == 'status':
        print(json.dumps(status(), ensure_ascii=False, indent=2))
        return 0
    cmd = argv[0]
    if cmd == 'disable':
        reason = ' '.join(argv[1:]) or 'manual'
        p = disable(reason)
        print(f'sidecar disabled: {p}')
        return 0
    if cmd == 'enable':
        ok = enable()
        print('sidecar enabled' if ok else 'sidecar already enabled (no file)')
        return 0
    print(f'unknown command: {cmd}', file=sys.stderr)
    print('usage: sidecar.py {status | disable [reason] | enable}', file=sys.stderr)
    return 2


if __name__ == '__main__':
    sys.exit(_cli(sys.argv[1:]))
