#!/usr/bin/env python3
"""Drive a running T3 server over HTTP; disclose no client IDs or credentials."""
import argparse, datetime, json, pathlib, urllib.request, urllib.parse, urllib.error
p=argparse.ArgumentParser()
p.add_argument('--origin', required=True)
p.add_argument('--commit', required=True)
p.add_argument('--side', required=True)
p.add_argument('--output', required=True)
a=p.parse_args()
class NoRedirect(urllib.request.HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl): return None
http=urllib.request.build_opener(NoRedirect)
def request(path, body=None):
    req=urllib.request.Request(a.origin+path, data=None if body is None else json.dumps(body).encode(), headers={} if body is None else {'Content-Type':'application/json'})
    try: return http.open(req)
    except urllib.error.HTTPError as e: return e
out=[]
def log(s): out.append(s); print(s, flush=True)
log('MCP OAuth resource indicator — real app HTTP capture')
log('Side: '+a.side+' | Commit: '+a.commit)
log('Environment: Linux; full T3 dev server; fresh isolated database; no seed')
log('Transport: loopback HTTP; no mocked services; redirects not followed')
discovery=request('/.well-known/oauth-protected-resource/mcp')
resource=json.load(discovery)['resource']
log('GET /.well-known/oauth-protected-resource/mcp -> '+str(discovery.status))
registered=request('/oauth/mcp/register', {'client_name':'Resource fragment evidence','redirect_uris':['http://localhost:51234/callback'],'grant_types':['authorization_code','refresh_token'],'token_endpoint_auth_method':'none'})
client=json.load(registered)
log('POST /oauth/mcp/register -> '+str(registered.status)+' (synthetic loopback client)')
results={}
for name, value in [('canonical',resource),('nonemptyFragment',resource+'#section'),('relative','/mcp'),('otherAudience','https://other.example/mcp'),('emptyFragment',resource+'#')]:
    query=urllib.parse.urlencode({'response_type':'code','client_id':client['client_id'],'redirect_uri':'http://localhost:51234/callback','code_challenge':'DeB41nTVkPwpbbYecrnqtVq7VXLezustdHAK4SWt13c','code_challenge_method':'S256','state':'evidence-state','resource':value})
    response=request('/oauth/mcp/authorize?'+query)
    location=response.headers.get('Location','')
    parsed=urllib.parse.urlsplit(location)
    params=urllib.parse.parse_qs(parsed.query,keep_blank_values=True)
    error=params.get('error',[None])[0]
    result=error or ('accepted' if parsed.path=='/connect-agent' else 'unexpected')
    results[name]=result
    log('\nGET /oauth/mcp/authorize with resource='+value)
    log('  HTTP '+str(response.status))
    if result=='accepted': log('  Location: /connect-agent?... (approval continues; error absent)')
    else: log('  Location: '+parsed.scheme+'://'+parsed.netloc+parsed.path+'?'+urllib.parse.urlencode({k:v[0] for k,v in params.items() if k in ['error','error_description','state']}))
    log('  Observed: '+result)
log('\nObserved results: '+json.dumps(results,sort_keys=True))
log('Empty fragment '+('REJECTED with invalid_target' if results['emptyFragment']=='invalid_target' else 'ACCEPTED; defect reproduced'))
run=pathlib.Path(a.output)/(a.side+'-'+datetime.datetime.now(datetime.timezone.utc).strftime('%Y%m%dT%H%M%SZ'))
run.mkdir(parents=True)
(run/'transcript.txt').write_text('\n'.join(out)+'\n')
(run/'observed.json').write_text(json.dumps({'side':a.side,'commit':a.commit,'results':results},indent=2))
