import re
from pathlib import Path

ROOT = Path(r'C:\SC\azure-cert-portal\js\data')
REQ_META = ['title','description','icon','level','passingScore','totalTime','questionCount','domains','msLearnUrl']
VALID_TYPES = {'single','multiple','scenario'}
VALID_DIFF = {'easy','medium','hard'}
issues=[]
ids={}

def extract_question_objects(text):
    m = re.search(r'questions\s*:\s*\[', text)
    if not m:
        return []
    i = m.end()
    objs=[]
    depth=0; start=None; in_str=None; esc=False
    while i < len(text):
        ch=text[i]
        if in_str:
            if esc:
                esc=False
            elif ch=='\\':
                esc=True
            elif ch==in_str:
                in_str=None
        else:
            if ch in "'\"":
                in_str=ch
            elif ch=='{':
                if depth==0: start=i
                depth+=1
            elif ch=='}':
                depth-=1
                if depth==0 and start is not None:
                    objs.append(text[start:i+1])
                    start=None
            elif ch==']' and depth==0:
                break
        i+=1
    return objs

for fp in sorted(ROOT.glob('*.js')):
    text = fp.read_text(encoding='utf-8')
    if text.count("'") % 2 != 0:
        issues.append((str(fp), '', 'Possible unmatched quote(s)'))
    if 'window.ExamData' in text:
        meta_m = re.search(r'meta\s*:\s*\{(.*?)\}\s*,\s*questions\s*:\s*\[', text, re.S)
        if meta_m:
            meta = meta_m.group(1)
            for k in REQ_META:
                if re.search(rf"\b{k}\s*:", meta) is None:
                    issues.append((str(fp), '', f'Missing meta field {k}'))
        for obj in extract_question_objects(text):
            qid_m = re.search(r"\bid\s*:\s*'([^']+)'", obj)
            qid = qid_m.group(1) if qid_m else ''
            if qid:
                if qid in ids:
                    issues.append((str(fp), qid, f'Duplicate question ID also in {ids[qid]}'))
                else:
                    ids[qid] = str(fp)
            else:
                issues.append((str(fp), '', 'Missing question id'))
            for field in ['type','domain','difficulty','scenario','question','options','correct','explanation','hint','reference']:
                if re.search(rf"\b{field}\s*:", obj) is None:
                    issues.append((str(fp), qid, f'Missing field {field}'))
            tm = re.search(r"type\s*:\s*'([^']+)'", obj)
            if tm and tm.group(1) not in VALID_TYPES:
                issues.append((str(fp), qid, f'Invalid type {tm.group(1)}'))
            dm = re.search(r"difficulty\s*:\s*'([^']+)'", obj)
            if dm and dm.group(1) not in VALID_DIFF:
                issues.append((str(fp), qid, f'Invalid difficulty {dm.group(1)}'))
            opts = re.findall(r"id\s*:\s*'([^']+)'\s*,\s*text\s*:\s*\{", obj)
            corrm = re.search(r'correct\s*:\s*\[(.*?)\]', obj, re.S)
            if corrm:
                corr = re.findall(r"'([^']+)'", corrm.group(1))
                for c in corr:
                    if c not in opts:
                        issues.append((str(fp), qid, f'Correct answer {c} not in options {opts}'))
            sc = re.search(r"scenario\s*:\s*(null|\{.*?\})\s*,\s*question\s*:", obj, re.S)
            if sc and sc.group(1).startswith('{'):
                s_en = re.search(r"en\s*:\s*'([^']*)'", sc.group(1))
                s_de = re.search(r"de\s*:\s*'([^']*)'", sc.group(1))
                s = ((s_en.group(1) if s_en else '') + ' ' + (s_de.group(1) if s_de else '')).strip()
                if len(s) < 30 or (re.search(r'You\b', s) and len(s) < 50):
                    issues.append((str(fp), qid, f'Suspicious scenario: {s[:80]}'))

for item in issues:
    print('|'.join(item))
