#!/usr/bin/env python3
import concurrent.futures, json, re, time, urllib.parse, urllib.request
from pathlib import Path

SRC=Path('/home/spazio/kingdom_calls/out/королевство 4_transcript.txt')
DST=Path('/home/spazio/kingdom_calls/final/Королевство 4 — полный перевод на русский.txt')
CACHE=Path('/home/spazio/kingdom_calls/.translation_cache_kingdom4.json')
pat=re.compile(r'^(\[[0-9:]+–[0-9:]+\])\s?(.*)$')
lines=SRC.read_text(encoding='utf-8').splitlines()
try: cache=json.loads(CACHE.read_text(encoding='utf-8'))
except Exception: cache={}

# Protect recurring specialist terminology and names from generic MT mistranslation.
protect = {
    'Access Consciousness':'ZXACCESSCONSCIOUSNESSZX',
    'Access Bars':'ZXACCESSBARSZX',
    'Keep Sweet, Pray and Obey':'ZXKEEPSWEETZX',
    'SuperSleeve.biz':'ZXSUPERSLEEVEDOTBIZZX',
    'COP':'ZXCOPZX',
}
restore = {
    'ZXACCESSCONSCIOUSNESSZX':'Access Consciousness',
    'ZXACCESSBARSZX':'Access Bars',
    'ZXKEEPSWEETZX':'«Будь послушной: молись и повинуйся»',
    'ZXSUPERSLEEVEDOTBIZZX':'SuperSleeve.biz',
    'ZXCOPZX':'COP',
}

def translate(s):
    if not s: return ''
    if s in cache: return cache[s]
    q=s
    for a,b in protect.items(): q=q.replace(a,b)
    url='https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=ru&dt=t&q='+urllib.parse.quote(q)
    err=None
    for attempt in range(7):
        try:
            req=urllib.request.Request(url,headers={'User-Agent':'Mozilla/5.0'})
            data=json.loads(urllib.request.urlopen(req,timeout=30).read().decode('utf-8'))
            out=''.join(x[0] for x in data[0] if x and x[0])
            for a,b in restore.items(): out=out.replace(a,b)
            cache[s]=out
            return out
        except Exception as e:
            err=e; time.sleep(min(10, .7*2**attempt))
    raise RuntimeError(f'Failed: {s!r}: {err}')

items=[]
for i,line in enumerate(lines):
    m=pat.match(line)
    if m: items.append((i,m.group(1),m.group(2)))

results={}
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as ex:
    futs={ex.submit(translate,text):(i,ts,text) for i,ts,text in items}
    for n,f in enumerate(concurrent.futures.as_completed(futs),1):
        i,ts,text=futs[f]
        results[i]=(ts,f.result())
        if n%100==0:
            CACHE.write_text(json.dumps(dict(cache),ensure_ascii=False,indent=1),encoding='utf-8')
            print(n,'/',len(items),flush=True)
CACHE.write_text(json.dumps(dict(cache),ensure_ascii=False,indent=1),encoding='utf-8')

out=[]
for i,line in enumerate(lines):
    if i==0: out.append('Перевод аудиотранскрипции: королевство 4.mp3')
    elif i==1: out.append('Язык перевода: русский')
    elif i==2: out.append('Источник: английская машинная транскрипция (faster-whisper small / cpu int8)')
    elif i in results:
        ts,tr=results[i]
        out.append(f'{ts} {tr}')
    else: out.append(line)
DST.parent.mkdir(parents=True,exist_ok=True)
DST.write_text('\n'.join(out)+'\n',encoding='utf-8')
print(DST)
