import subprocess,os,re,json,sys
ROOT='/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/insuniverse-server'
OUT='/home/madsc/work/insuniverse-temp/.worktrees/admin-rbac/.local/analysis-impl/neg'
SCOPE='apps/api/src/modules/auth/access-control/analysis-scope.ts'
CTRL='apps/api/src/modules/analyze/analyze-admin.controller.ts'
HELP='apps/api/src/helpers/admin-viewer.helper.ts'
DIS='apps/api/src/modules/disease/disease.service.ts'
DIS_R='apps/api/src/modules/disease/disease.repository.ts'
port=subprocess.check_output(['docker','port','analysis-impl-mysql','3306'],text=True).strip().rsplit(':',1)[1]
CASES=[
 ('조직 조건 제거',[(SCOPE,"""  if (s.orgPath)
    w.push(
      sql`EXISTS (SELECT 1 FROM tn_agency_organization o WHERE o.org_id = ${tnMember.orgId} AND o.org_path LIKE ${s.orgPath + '%'})`,
    );
""","")]),
 ('수준 조건 제거',[(SCOPE,"""  if (admin?.role === 'corp') where.push(gte(tnAgency.agcAnalysisView, 2));
""","")]),
 ('삭제 조건 제거',[(SCOPE,"""  const w: SQL[] = [eq(tnOrderDetail.oddDeletion, 0)];
""","""  const w: SQL[] = [];
""")]),
 ('빈 sagId 통과',[(SCOPE,"""  if (a?.role === 'sales') return a.sagId && a.sagId > 0 ? { sagId: a.sagId } : null;
""","""  if (a?.role === 'sales') return { sagId: a.sagId ?? undefined };
""")]),
 ('클래스에서 AnalysisRowGuard 제거',[(CTRL,"""  CorpAnalysisViewGuard,
  AnalysisRowGuard,
)""","""  CorpAnalysisViewGuard,
)""")]),
 ('assertOddOwner 가 옛 기업 비교로 돌아감',[(HELP,"""  if (!admin || oddId == null) return false;
""","""  if (!admin || oddId == null) return false;
  const a = admin as { role?: string; agcId?: number; ownerAgcId?: number };
  if (a.role === 'admin') return true;
  if (a.role === 'corp') return (admin as any).__ownerAgcId != null && Number((admin as any).__ownerAgcId) === Number(a.agcId);
"""),(DIS,"""    if (isAdminViewerAllowed(admin, oddId)) return;""","""    (admin as any) && ((admin as any).__ownerAgcId = (await this.diseaseRepository.findOwnerAgc(oddId)));
    if (isAdminViewerAllowed(admin, oddId)) return;"""),(DIS_R,"""  async findOrderOwner(
""","""  async findOwnerAgc(oddId: number) {
    const [row] = await this.drizzle
      .select({ agcId: sql<number>`(SELECT m.agc_id FROM tn_member m WHERE m.mem_id = ${tnUser.memId})` })
      .from(tnOrderDetail)
      .innerJoin(tnUser, eq(tnUser.usrId, tnOrderDetail.usrId))
      .where(eq(tnOrderDetail.oddId, oddId));
    return row?.agcId;
  }

  async findOrderOwner(
""")]),
]
results=[]
env=dict(os.environ,ANALYZE_SALES_SCOPE_MYSQL_PORT=port)
only=sys.argv[1:] 
for name,edits in CASES:
    if only and name not in only: continue
    assert subprocess.run(['git','diff','--quiet'],cwd=ROOT).returncode==0, 'tree dirty'
    try:
        for f,a,b in edits:
            p=os.path.join(ROOT,f); s=open(p,encoding='utf8').read()
            assert a in s,(name,f,a[:40])
            open(p,'w',encoding='utf8').write(s.replace(a,b,1))
        log=os.path.join(OUT,re.sub(r'\W+','_',name)+'.log')
        r=subprocess.run(['systemd-run','--user','--scope','-q','-p','MemoryMax=3G','-p','MemorySwapMax=0','npx','jest','--maxWorkers=2','--forceExit','--runTestsByPath','apps/api/src/modules/analyze/analysis-access.mysql.spec.ts','apps/api/src/modules/auth/access-control/analysis-scope.spec.ts','apps/api/src/modules/analyze/analysis-row.guard.spec.ts','apps/api/src/modules/auth/access-contract/access-contract.spec.ts','apps/api/src/helpers/admin-viewer.helper.spec.ts'],cwd=ROOT,env=env,stdout=open(log,'w'),stderr=subprocess.STDOUT,timeout=400)
        t=open(log,encoding='utf8').read()
        fails=sorted(set(re.findall(r'^\s+● (.+)$',t,re.M)))
        wrong=re.findall(r'^\s+\+\s+"([^"]{0,220})',t,re.M)[:4]
        total=re.search(r'^Tests:.*$',t,re.M)
        results.append({'case':name,'rc':r.returncode,'tests':total.group(0) if total else None,'fails':fails,'sample':wrong})
        print(name,r.returncode,total.group(0) if total else None); print('\n'.join('  '+f[:150] for f in fails)); print('\n'.join('    e.g. '+w[:200] for w in wrong[:2]))
    finally:
        for f,_,_ in edits:
            subprocess.run(['git','checkout','--',f],cwd=ROOT)
    assert subprocess.run(['git','diff','--quiet'],cwd=ROOT).returncode==0
json.dump(results,open(os.path.join(OUT,'neg-results.json'),'w'),ensure_ascii=False,indent=1)
