#!/usr/bin/env python3
"""
Messenger → ITSM 작업지시 송수신 테스트

흐름:
1. Messenger 앱에서 SR(작업지시) 등록
2. ITSM에서 SR 상태 변경 (승인 → 진행 → 완료)
3. Messenger 앱으로 상태 변경 알림 수신 (WebSocket)
4. AI 챗봇으로 자연어 작업지시 → SR 자동 생성
"""
import paramiko, time, sys

HOST='101.79.17.164'; USER='root'; PASS='1q2w3e!Q'
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(HOST, username=USER, password=PASS, timeout=15)
sftp = client.open_sftp()

script = r"""
import http.client, json, sys, time, secrets

HOST = 'localhost'; PORT = 8001
RESULTS = []
SR_ID = None  # 테스트에서 생성한 SR ID 저장

def api(method, path, data=None, token=None):
    conn = http.client.HTTPConnection(HOST, PORT, timeout=10)
    headers = {'Content-Type':'application/json'}
    if token: headers['Authorization'] = 'Bearer ' + token
    body = json.dumps(data).encode() if data else None
    conn.request(method, path, body=body, headers=headers)
    r = conn.getresponse(); raw = r.read()
    try: return json.loads(raw), r.status
    except: return {'raw': raw.decode()[:300]}, r.status

def test(name, fn):
    try:
        r = fn(); ok = True
    except Exception as e: r = str(e)[:100]; ok = False
    RESULTS.append((name, ok, str(r)[:100]))
    print(('PASS' if ok else 'FAIL') + ' ' + name + ': ' + str(r)[:90])
    return r if ok else None

print()
print('='*65)
print('Messenger -> ITSM 작업지시 송수신 테스트')
print('='*65)

# 로그인
d, s = api('POST','/api/auth/login',{'username':'admin','password':'1111'})
TOKEN = d.get('access_token','')
if not TOKEN: print('로그인 실패'); sys.exit(1)
print(f'  로그인 OK (token={TOKEN[:15]}...)')
print()

# ── 단계 1: Messenger 앱에서 작업지시 등록 ─────────────────────────────
print('[단계 1] Messenger 앱 → ITSM 작업지시 등록')

suffix = secrets.token_hex(3).upper()

def step1_sr():
    global SR_ID
    # Messenger 앱의 SR 등록 화면에서 직접 POST
    d, s = api('POST','/api/tasks', {
        'title':       f'[Messenger] 웹서버 재시작 요청 {suffix}',
        'description': 'GUARDiA Messenger 앱에서 직접 등록한 작업지시입니다.\n'
                       '서버: web-01.zioinfo.co.kr\n'
                       '작업: nginx 재시작\n'
                       '요청자: admin (Messenger 앱)',
        'priority':    'HIGH',
        'sr_type':     'RESTART',
        'requested_by': 'admin',
    }, token=TOKEN)
    if s in [200,201]:
        SR_ID = d.get('id') or d.get('sr_id')
        return f'HTTP {s} SR등록 성공: id={d.get("id")} sr_id={d.get("sr_id","?")} title={d.get("title","?")[:30]}'
    return f'HTTP {s}: {d.get("detail","?")[:80]}'

test('S1-1 Messenger→ITSM SR 등록 (POST /api/tasks)', step1_sr)

# SR 목록에서 방금 생성한 SR 확인
def step1_verify():
    d, s = api('GET','/api/tasks?size=1',token=TOKEN)
    if isinstance(d,list) and len(d)>0:
        latest = d[0]
        return f'HTTP {s} 최신SR: {latest.get("sr_id","?")} [{latest.get("status","?")}] {latest.get("title","?")[:30]}'
    return f'HTTP {s} {type(d)}'
test('S1-2 ITSM SR 목록 확인', step1_verify)

print()

# ── 단계 2: ITSM에서 SR 상태 변경 ──────────────────────────────────────
print('[단계 2] ITSM SR 상태 변경 → Messenger 알림 수신')

def step2_approve():
    # SR을 APPROVED 상태로 변경 (승인)
    if not SR_ID: return 'SR_ID 없음'
    # PATCH /api/tasks/{id}/status 또는 PUT
    d, s = api('PATCH', f'/api/tasks/{SR_ID}/status', {'status':'APPROVED'}, token=TOKEN)
    if s in [200,201]:
        return f'HTTP {s} 상태변경: APPROVED -> WebSocket 알림 발생'
    # 다른 경로 시도
    d2, s2 = api('PUT', f'/api/tasks/{SR_ID}', {'status':'IN_PROGRESS'}, token=TOKEN)
    return f'HTTP {s} / {s2}: {d.get("detail","?")} / {d2.get("status","?")}'
test('S2-1 SR 승인 (APPROVED) → 앱 알림 수신', step2_approve)

def step2_inprogress():
    if not SR_ID: return 'SR_ID 없음'
    d, s = api('PATCH', f'/api/tasks/{SR_ID}/status', {'status':'IN_PROGRESS'}, token=TOKEN)
    if s in [200,201]:
        return f'HTTP {s} 상태변경: IN_PROGRESS -> 앱에 진행중 알림'
    return f'HTTP {s}: {d.get("detail","?")[:60]}'
test('S2-2 SR 진행 (IN_PROGRESS) → 앱 알림 수신', step2_inprogress)

def step2_complete():
    if not SR_ID: return 'SR_ID 없음'
    d, s = api('PATCH', f'/api/tasks/{SR_ID}/status', {'status':'COMPLETED'}, token=TOKEN)
    if s in [200,201]:
        return f'HTTP {s} 상태변경: COMPLETED -> 앱에 완료 알림'
    return f'HTTP {s}: {d.get("detail","?")[:60]}'
test('S2-3 SR 완료 (COMPLETED) → 앱 알림 수신', step2_complete)

print()

# ── 단계 3: AI 챗봇으로 작업지시 ──────────────────────────────────────
print('[단계 3] Messenger AI 챗봇 → 자연어 작업지시')

def step3_ai_cmd():
    d, s = api('POST','/api/chatbot/message',
        {'message': '웹서버 nginx를 재시작해 주세요. 긴급합니다.'},
        token=TOKEN)
    reply = d.get('reply', d.get('message', d.get('response', str(d)[:80])))
    return f'HTTP {s} AI응답: {str(reply)[:80]}'
test('S3-1 AI챗봇 자연어 작업지시 (nginx 재시작)', step3_ai_cmd)

def step3_ai_sr():
    d, s = api('POST','/api/chatbot/message',
        {'message': 'SR 등록해줘: 데이터베이스 백업 실행 요청, 우선순위 HIGH'},
        token=TOKEN)
    reply = d.get('reply', d.get('message', str(d)[:80]))
    return f'HTTP {s} AI응답: {str(reply)[:80]}'
test('S3-2 AI챗봇 SR 자동 생성 요청', step3_ai_sr)

def step3_nlcmd():
    # 자연어 명령 (nlcmd)
    d, s = api('POST','/api/ai-cmd',
        {'message': '현재 서버 상태를 확인해줘', 'channel': 'messenger'},
        token=TOKEN)
    return f'HTTP {s}: {str(d)[:80]}'
test('S3-3 AI 자연어 명령 (서버 상태 확인)', step3_nlcmd)

print()

# ── 단계 4: WebSocket 이벤트 직접 확인 ─────────────────────────────────
print('[단계 4] WebSocket 이벤트 상태 확인')

def step4_ws():
    d, s = api('GET','/api/ws/status',token=TOKEN)
    conns = d.get('total_connections', d.get('connection_count', 0))
    channels = d.get('channels', [])
    return f'HTTP {s} 연결={conns}개 채널={channels[:4]}'
test('S4-1 WebSocket 연결 상태 (앱 연결 수)', step4_ws)

def step4_audit():
    d, s = api('GET','/api/audit?size=5',token=TOKEN)
    items = d if isinstance(d,list) else d.get('items',d.get('content',[]))
    logs = [(i.get('action','?'), i.get('username','?')) for i in items[:3]]
    return f'HTTP {s} 최근감사: {logs}'
test('S4-2 감사 로그 (작업지시 이력 추적)', step4_audit)

print()
print('='*65)
passed = sum(1 for _,ok,_ in RESULTS if ok)
print(f'결과: {passed}/{len(RESULTS)} PASS')
print()
for name,ok,d in RESULTS:
    print(f'  {"OK  " if ok else "FAIL"} {name}')
print()
print('='*65)
print()
print('[작업지시 전체 흐름]')
print()
print('  Messenger 앱                    GUARDiA ITSM')
print('       |                                |')
print('  SR 등록 탭에서 입력 ──────────────> POST /api/tasks')
print('       |                                |')
print('  AI챗봇: "nginx 재시작해줘" ─────> /api/chatbot/message')
print('       |                                | (AI가 SR 자동 생성)')
print('       |  <── WebSocket 상태 알림 ──── 관리자 승인')
print('       |  <── WebSocket 완료 알림 ──── 작업 완료 처리')
print()
print('[앱에서 확인하는 방법]')
print('1. 앱 SR탭 -> "새 SR" 버튼 -> 제목/설명/우선순위 입력 -> 등록')
print('   → ITSM 관리자 웹(http://101.79.17.164:8001)에서 SR 확인')
print()
print('2. 앱 AI채팅탭 -> "서버 nginx 재시작 요청해줘" 입력')
print('   → AI가 자동으로 SR 생성 후 응답')
print()
print('3. 앱 알림탭 -> ⚡ 실시간 연결 초록 표시 확인')
print('   → ITSM에서 SR 상태 변경 시 즉시 알림 수신')
"""

with sftp.open('/tmp/test_wo.py','w') as f: f.write(script)
sftp.close()

chan = client.get_transport().open_session()
chan.set_combine_stderr(True)
chan.exec_command('python3 /tmp/test_wo.py 2>&1')
start = time.time()
while not chan.exit_status_ready():
    if chan.recv_ready(): sys.stdout.buffer.write(chan.recv(8192)); sys.stdout.flush()
    if time.time()-start > 50: break
    time.sleep(0.3)
while chan.recv_ready(): sys.stdout.buffer.write(chan.recv(8192))
sys.stdout.flush()
chan.recv_exit_status()
client.close()
