"""MROI-01: local-only ct policy client; never starts a container or enrolls with Web."""
import argparse
import json
from pathlib import Path

import compose_backend as backend
import field_profiles as fp
import server_context as server
from field_ui import print, input

WORKER = r'''
import json, os, sys, urllib.request, urllib.error
from pathlib import Path
try:
    body=json.load(sys.stdin)
    token=Path(os.environ['CONTEXTRA_CONTROL_TOKEN_FILE']).read_text().strip()
    data=json.dumps(body['body']).encode() if body['body'] is not None else None
    req=urllib.request.Request('http://127.0.0.1:5000/internal/secure-control/roi-policy',
        data=data, method=body['method'], headers={'Authorization':'Bearer '+token,'Content-Type':'application/json'})
    opener=urllib.request.build_opener(urllib.request.ProxyHandler({}))
    try:
        response=opener.open(req,timeout=5)
    except urllib.error.HTTPError as error:
        response=error
    with response:
        result=json.loads(response.read(65537))
    print(json.dumps(result,ensure_ascii=False))
except Exception:
    print(json.dumps({'error':'ROI_CONTROL_UNAVAILABLE','message':'Runtime 관리 API를 확인하세요. 자동 기동하지 않았습니다.'},ensure_ascii=False))
'''


def context():
    if not server.portable():
        raise ValueError('ROI_SERVER_ADAPTER_REVIEW_REQUIRED')
    server.guard_disks()
    _, _, _, approved, live, _ = backend.inspect()
    if approved != live:
        raise ValueError('REVIEW_PENDING_CONFIG_FIRST')
    service = approved['services']['analytics']
    inside = service.get('environment', {}).get('CONTEXTRA_ROI_POLICY_FILE')
    if not inside:
        raise ValueError('CONTEXTRA_ROI_POLICY_FILE 배포 설정이 필요합니다. 자동 변경하지 않습니다.')
    path = Path(inside)
    mounts = [m for m in service.get('volumes', []) if m['type']=='bind'
              and (path == Path(m['target']) or Path(m['target']) in path.parents)]
    if len(mounts) != 1 or path == Path(mounts[0]['target']):
        raise ValueError('ROI_POLICY_DIRECTORY_BIND_REQUIRED')
    source = fp.safe_path(Path(mounts[0]['source'])/path.relative_to(mounts[0]['target']))
    if '..' in source.parts:
        raise ValueError('ROI_POLICY_PATH_INVALID')
    if source.is_relative_to(server.path('source', '/workspace/contextra/source')):
        raise ValueError('ROI_POLICY_MUST_BE_OUTSIDE_SOURCE')
    rows = [r for r in backend.containers() if r['Config']['Labels']['com.docker.compose.service']
            == server.service('analytics') and r['State']['Running']]
    if len(rows) != 1:
        raise ValueError('Runtime 관리 API가 실행 중이어야 합니다. 자동 Start하지 않습니다. 편집 원본: '+str(source))
    return source, rows[0]['Id']


def call(container, method='GET', body=None):
    from maintenance_process import run
    result = run(['docker','exec','-i',container,'python3','-c',WORKER],
        input=json.dumps(dict(method=method,body=body)).encode(), capture_output=True, timeout=8, check=True)
    value = json.loads(result.stdout)
    if value.get('error') and not (method == 'GET' and 'effective' in value):
        raise ValueError(value['error']+': '+value.get('message', '설정 원본과 적용값을 확인하세요.'))
    return value


def main(args):
    parser = argparse.ArgumentParser(description='ct roi status/edit/apply')
    parser.add_argument('action', nargs='?', default='status', choices=('status','edit','apply'))
    action = parser.parse_args(args).action
    source, container = context()
    status = call(container)
    print('일반 편집 원본:', source)
    print('Runtime 적용 파일:', status['appliedPath'])
    print('설정값:', status['configured'], '적용값:', status['effective'])
    if status.get('error'):
        print('설정 파일 오류:', status['error'], '/ 기존 적용값은 유지합니다.')
    print('허용 필드: mode, max_rois, max_rules, full_frame_roi_id / 적용: ct roi apply')
    if action == 'status':
        return status
    if action == 'edit':
        value = dict(status['configured'] or status['effective'])
        for key in ('mode','max_rois','max_rules','full_frame_roi_id'):
            raw = input(f'{key} [{value[key]}; Enter=현재값 유지]: ').strip()
            if raw:
                value[key] = raw if key == 'mode' else int(raw)
        if value['mode'] not in ('legacy','multi_roi'):
            raise ValueError('mode: legacy/multi_roi')
        fp.atomic(source, value, user=True)
        print('원본만 저장했습니다. 검증·적용: ct roi apply. 채널 자동 Start 없음.')
        return
    print('현재 채널과 충돌하는 상한 변경은 거절합니다. 채널은 자동 재시작하지 않습니다.')
    if input('관리 설정을 적용하려면 APPLY 입력: ') != 'APPLY':
        return
    result = call(container, 'PATCH', dict(expectedRevision=status['revision'],
                                        configuredRevision=status['configuredRevision']))
    print('적용값:', result['effective'], '채널 자동 Start 없음.')
    return result
