"""Bounded terminal picker for public certificates; never traverses symlinks."""
try:
    import curses
except ImportError:
    curses = None
import hashlib
import os
from pathlib import Path
import subprocess

import field_profiles as profiles
from field_ui import print, input, language


def entries(folder):
    folder=profiles.safe_path(folder)
    items=[]
    for p in folder.iterdir():
        if p.is_symlink() or p.name.startswith('.'): continue
        if p.is_dir() or (p.is_file() and p.suffix.lower() in ('.crt','.pem','.cer')): items.append(p)
        if len(items)>500: raise ValueError('폴더 항목이 너무 많습니다. 더 좁은 경로를 입력하세요.')
    return sorted(items,key=lambda p:(not p.is_dir(),p.name.casefold()))


def numbered(folder):
    while True:
        print('\n폴더:',folder,' 0=상위 / q=취소')
        rows=entries(folder)
        for i,p in enumerate(rows,1): print(i, '[DIR]' if p.is_dir() else '[CA]',p.name)
        value=input('번호: ').strip()
        if value.lower()=='q': return None
        if value=='0': folder=folder.parent; continue
        if not value.isdigit() or not 1<=int(value)<=len(rows): continue
        chosen=rows[int(value)-1]
        if chosen.is_dir():folder=chosen
        else:return chosen


def screen(stdscr,folder):
    pos=0
    curses.curs_set(0)
    while True:
        rows=[folder.parent]+entries(folder)
        pos=min(pos,len(rows)-1)
        stdscr.erase(); h,w=stdscr.getmaxyx()
        if h<8 or w<30: raise curses.error('small terminal')
        stdscr.addnstr(0,0,str(folder),w-1)
        stdscr.addnstr(1,0,'UP/DOWN Enter=open/select  Backspace=parent  q=cancel',w-1)
        offset=max(0,pos-(h-5))
        for line,i in enumerate(range(offset,min(len(rows),offset+h-4)),3):
            p=rows[i];label='..' if i==0 else ('[DIR] ' if p.is_dir() else '[CA] ')+p.name
            stdscr.addnstr(line,0,label,w-1,curses.A_REVERSE if i==pos else 0)
        key=stdscr.getch()
        if key in (ord('q'),27):return None
        if key==curses.KEY_UP:pos=max(0,pos-1)
        elif key==curses.KEY_DOWN:pos=min(len(rows)-1,pos+1)
        elif key in (curses.KEY_BACKSPACE,127,8):folder=folder.parent;pos=0
        elif key in (10,13,curses.KEY_ENTER):
            p=rows[pos]
            if p.is_dir():folder=p;pos=0
            else:return p


def choose():
    print('1 기본 반입 폴더  2 마운트된 USB  3 경로 입력  4 번호형 탐색  Enter=1')
    choice=input('선택: ').strip() or '1'
    folder=profiles.SETUP/'inbox'
    if choice=='2':
        import field_usb
        folder=field_usb.choose()
        if folder is None:return None
    elif choice=='3':
        folder=profiles.safe_path(input('파일 또는 폴더 절대 경로: ').strip())
        if folder.is_file():return folder
    if curses is None or language()=='en' or choice=='4' or not os.isatty(0) or os.environ.get('TERM','dumb')=='dumb':return numbered(folder)
    try:return curses.wrapper(screen,folder)
    except curses.error:return numbered(folder)


def import_ca(p,source=None):
    import connection
    source=profiles.safe_path(source) if source else choose()
    if source is None:return
    connection.verify_ca(source)
    print('선택 파일:',source,'파일 SHA256:',hashlib.sha256(source.read_bytes()).hexdigest())
    print('별도로 전달받은 인증서 fingerprint와 대조하세요. private key는 반입하지 않습니다.')
    if input('이 CA를 선택 Web의 신뢰 기준으로 복사하려면 TRUST 입력: ')!='TRUST':return
    target=profiles.ca_path(p)
    target.parent.mkdir(parents=True,exist_ok=True,mode=0o700)
    if os.geteuid()==0:
        u=profiles.account();os.chown(target.parent,u.pw_uid,u.pw_gid)
    if target.exists():
        backup=target.with_name(target.name+'.previous-'+hashlib.sha256(target.read_bytes()).hexdigest()[:12])
        if not backup.exists():profiles.atomic(backup,target.read_bytes(),user=True)
    profiles.atomic(target,source.read_bytes(),user=True)
    print('복사 완료:',target,'USB original preserved.')
    from field_cli import next_step
    next_step(p)
