"""Local-only JSON API. Start: python -m research.rates338.server"""
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from threading import RLock
import json
from .engine import Registry,InputError
REGISTRY=Registry(); LOCK=RLock()
class Handler(BaseHTTPRequestHandler):
    def do_POST(self):
        try:
            if not self.path.startswith('/v1/'): raise InputError('route','Use /v1/{operation}','NOT_FOUND')
            n=int(self.headers.get('Content-Length',0))
            if not 0<n<=1000000: raise InputError('body','Body must contain 1–1000000 bytes')
            p=json.loads(self.rfile.read(n))
            with LOCK:
                if len(REGISTRY.objects)>5000: raise InputError('registry','Local demo registry full; restart to clear','CAPACITY')
                result=REGISTRY.call(self.path.split('/')[-1],p)
            self.reply(200,{'ok':True,'data':result})
        except InputError as e: self.reply(404 if e.code=='NOT_FOUND' else 422,{'ok':False,'error':{'code':e.code,'field':e.field,'message':str(e)}})
        except (ValueError,TypeError,KeyError,OverflowError) as e: self.reply(422,{'ok':False,'error':{'code':'INVALID_INPUT','field':'payload','message':'Malformed JSON, missing field or incompatible input type'}})
    def reply(self,status,data):
        body=json.dumps(data,allow_nan=False).encode(); self.send_response(status); self.send_header('Content-Type','application/json; charset=utf-8'); self.send_header('Content-Length',str(len(body))); self.end_headers(); self.wfile.write(body)
    def log_message(self,*args): pass
if __name__=='__main__':
    print('Local API: http://127.0.0.1:8338/v1/{operation}; memory only; no public hosting')
    ThreadingHTTPServer(('127.0.0.1',8338),Handler).serve_forever()
