"""Private HTTPS pilot. No credentials in argv/logs; synthetic data is opt-in."""
import argparse,os,time,json,uuid,urllib.request,urllib.error,ssl,math
class NoRedirect(urllib.request.HTTPRedirectHandler):
 def redirect_request(self,*args,**kwargs):return None

def read_channels(count):
 # Replace with real acquisition. Return None when disconnected.
 return [None]*count

def main():
 parser=argparse.ArgumentParser();parser.add_argument('--samples',type=int,default=0);parser.add_argument('--synthetic',action='store_true');parser.add_argument('--channels',type=int,choices=range(1,5),default=1);parser.add_argument('--credential-pipe');args=parser.parse_args()
 base=os.environ['ROASTLINK_API_URL'].rstrip('/')
 if not base.startswith('https://'):raise SystemExit('Verified HTTPS endpoint required')
 key=open(args.credential_pipe).read().strip() if args.credential_pipe else os.environ['ROASTLINK_DEVICE_KEY'];device=os.environ['ROASTLINK_DEVICE_ID'];boot=str(uuid.uuid4());interval=max(5,int(os.environ.get('ROASTLINK_INTERVAL_S','30')))
 opener=urllib.request.build_opener(NoRedirect(),urllib.request.HTTPSHandler(context=ssl.create_default_context()))
 if args.synthetic:print('SYNTHETIC temperatures; not physical sensor measurements',flush=True)
 seq=0
 while args.samples==0 or seq<args.samples:
  values=[22.5+i+math.sin(seq/3) for i in range(args.channels)] if args.synthetic else read_channels(args.channels)
  values=[v if type(v) in (int,float) and math.isfinite(v) and -100<=v<=600 else None for v in values]
  body=json.dumps({'version':2,'device_id':device,'message_id':str(uuid.uuid4()),'sampled_at':time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime()),'boot_id':boot,'sequence':seq,'sample_age_ms':0,'channels':[{'id':i+1,'temperature_c':v,'valid':v is not None,'fault':None if v is not None else 'sensor_not_configured'} for i,v in enumerate(values)]},allow_nan=False).encode();seq+=1
  for attempt in range(3):
   try:
    req=urllib.request.Request(base+'/v1/device/telemetry',data=body,headers={'Content-Type':'application/json','Authorization':'Bearer '+key})
    with opener.open(req,timeout=10) as response:print('Telemetry status',response.status,flush=True)
    break
   except urllib.error.HTTPError as e:
    e.close()
    if e.code in (401,403):raise SystemExit('Credential rejected; stopped')
    if e.code==409:raise SystemExit('Message conflict/replay; stopped')
    if e.code not in (429,503):raise SystemExit('Payload rejected: '+str(e.code))
   except urllib.error.URLError:pass
   if attempt<2:time.sleep(min(30,5*2**attempt))
   else:print('Bounded retry exhausted; packet discarded',flush=True)
  if args.samples==0 or seq<args.samples:time.sleep(interval)
if __name__=='__main__':main()
