"""Generate an OpenAPI-shaped document from explicit Python exercise metadata.
This is not Microsoft.AspNetCore.OpenApi execution or a network capture.
"""
from pathlib import Path
import argparse,json,hashlib
def digest(x):return hashlib.sha256(json.dumps(x,ensure_ascii=False,sort_keys=True,separators=(',',':')).encode()).hexdigest()
def generate(implementation):
 paths={}
 for e in implementation['endpoints']:
  response={}
  for s in e['status_code_contract']:
   media='application/problem+json' if s>=400 else 'application/json'
   response[str(s)]={'description':str(s),'content':{media:{'schema':{'$ref':'#/components/schemas/'+('Problem' if s>=400 else e['response_schema_ref'])}}}}
   if s==201:response[str(s)]['headers']={'Location':{'schema':{'type':'string'}}}
   if s==401:response[str(s)]['headers']={'WWW-Authenticate':{'schema':{'type':'string'}}}
  op={'operationId':e['endpoint_id'],'responses':response,'security':[{'bearerAuth':[]}] if e['authorization_policy'] else [],'x-required-policy':e['authorization_policy']}
  if '{id}' in e['openapi_path']:op['parameters']=[{'name':'id','in':'path','required':True,'schema':{'type':'integer'}}]
  if e['http_method']=='POST':op.setdefault('parameters',[]).append({'name':'Idempotency-Key','in':'header','required':True,'schema':{'type':'string','minLength':1}})
  if e['request_schema_ref']!='NONE':op['requestBody']={'required':True,'content':{e['request_content_type']:{'schema':{'$ref':'#/components/schemas/'+e['request_schema_ref']}}}}
  paths.setdefault(e['openapi_path'],{})[e['http_method'].lower()]=op
 return {'openapi':'3.1.1','info':{'title':'MAKNOW synthetic orders contract','version':'1'},'paths':paths,'components':{'schemas':implementation['schemas'],'securitySchemes':{'bearerAuth':{'type':'http','scheme':'bearer'}}},'x-evidence-kind':'PYTHON_METADATA_GENERATION_NOT_ASPNET','x-implementation-digest':digest(implementation)}
if __name__=='__main__':
 p=argparse.ArgumentParser(description=__doc__);p.add_argument('implementation',type=Path);p.add_argument('output',type=Path);a=p.parse_args()
 with a.output.open('x') as f:json.dump(generate(json.loads(a.implementation.read_text())),f,ensure_ascii=False,indent=2);f.write('\n')
