"""Authored bilingual annotations: count and validate records, not translation quality automatically."""
import json,hashlib,copy
SOURCE=['Batch R-17 contains 12 sensor readings.','Values are in millivolts, not volts.','A checksum is an integrity field, not a password.','The exported table excludes incomplete readings.','Calibration has not been verified.','The probe name is Luma.']
A=['بستهٔ R-17 شامل ۱۲ قرائتِ حسگر است.','مقادیر بر حسب میلی‌ولت هستند، نه ولت.','مجموعِ وارسی یک فیلدِ تمامیت است، نه گذرواژه.','جدولِ صادرشده قرائت‌هایِ ناقص را کنار می‌گذارد.','کالیبراسیون هنوز تأیید نشده است.','نامِ پروب لوما است.']
B=['بستهٔ R-17 شامل ۲۱ قرائتِ حسگر است.','مقادیر بر حسب ولت هستند.','گذرواژه یک فیلدِ تمامیت است.','جدولِ صادرشده قرائت‌هایِ ناقص را هم شامل می‌شود.','کالیبراسیون تأیید شده است.','نامِ پروب لوما است.']
TYPES=['accuracy-number','accuracy-unit','terminology','accuracy-polarity','accuracy-polarity']
def digest(parts):return hashlib.sha256(chr(10).join(parts).encode('utf-8')).hexdigest()
def validate_and_count(source,translations,annotations,expected_source_sha):
    if digest(source)!=expected_source_sha:raise ValueError('source version mismatch')
    counts={}
    for name,target in translations.items():
        rows=[r for r in annotations if r['translation']==name]
        if len(target)!=len(source) or sorted(r['unit'] for r in rows)!=list(range(1,len(source)+1)):raise ValueError('one annotation per source unit')
        count={'pass':0,'issue':0,'unknown':0,'major':0}
        for row in rows:
            if row['status'] not in ['pass','issue','unknown']:raise ValueError('unknown status')
            if row['status']=='issue' and (row['severity']!='major' or row['type'] not in TYPES):raise ValueError('exercise issue taxonomy')
            if row['status']!='issue' and (row['type'] is not None or row['severity'] is not None):raise ValueError('unjudged/pass not an issue')
            count[row['status']]+=1;count['major']+=row['severity']=='major'
        counts[name]=count
    return counts
def demo():
    rows=[]
    for name in ['A','B']:
        for i in range(6):
            unknown=i==5;issue=name=='B' and not unknown
            rows.append({'translation':name,'unit':i+1,'status':'unknown' if unknown else 'issue' if issue else 'pass','type':TYPES[i] if issue else None,'severity':'major' if issue else None,'origin':'author manual annotation','note':'Luma transliteration awaits glossary owner' if unknown else 'authored unit-level judgment'})
    counts=validate_and_count(SOURCE,{'A':A,'B':B},rows,digest(SOURCE))
    assert counts=={'A':{'pass':5,'issue':0,'unknown':1,'major':0},'B':{'pass':0,'issue':5,'unknown':1,'major':5}}
    mutations=[]
    for name,source,annotations,expected in [('missing annotation',SOURCE,rows[:-1],digest(SOURCE)),('changed source',SOURCE+['extra'],rows,digest(SOURCE))]:
        try:validate_and_count(source,{'A':A,'B':B},annotations,expected)
        except ValueError:mutations.append({'name':name,'rejected':True})
        else:raise AssertionError(name)
    return {'source_units':SOURCE,'source_sha256':digest(SOURCE),'translations':{'A':A,'B':B},'translations_origin':'both written manually for this exercise; no NMT engine executed','annotations':rows,'counts':counts,'rejected_mutations':mutations,'automated_semantic_judgment':False,'standard_MQM_score_claimed':False}
if __name__=='__main__':print(json.dumps(demo(),ensure_ascii=False,indent=2))
