package com.android.commands.monkey.ape.jev;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.Properties;
import org.json.*;
import com.android.commands.monkey.ape.utils.ApeSnapshot;

/** Device admission through the actual synchronous Probe transport and validator. */
public final class ProbePreflight {
    public static void main(String[] args)throws Exception {
        Properties properties=new Properties();
        try(InputStream input=new FileInputStream(args[0])){properties.load(input);}
        String endpoint=properties.getProperty("ape.jev.endpoint"),model=properties.getProperty("ape.jev.model");
        int timeout=Integer.parseInt(properties.getProperty("ape.jev.probeTimeoutMs","5000"));
        int bytes=Integer.parseInt(properties.getProperty("ape.jev.maxRequestBytes","32768"));
        ApeSnapshot.requireRegionOff();ApeSnapshot.preflight();
        JSONObject identity=ApeSnapshot.identity();
        String id=identity.optString("checkpoint_id","device")+"-"+Paths.get(args[1]).getFileName().toString();
        String fixture=new String(Files.readAllBytes(Paths.get(args[2])),StandardCharsets.UTF_8);
        JevProtocol.Request request=JevProtocol.wire(id,fixture,bytes,model);
        Path output=Paths.get(args[1]);Files.createDirectories(output);
        if(Files.exists(output.resolve("receipt.json")))throw new IOException("Preflight receipt already exists");
        JSONObject receipt=ApeSnapshot.identify(new JSONObject().put("request_id",id).put("endpoint",endpoint)
            .put("model_requested",model).put("request_bytes",request.requestBytes).put("fixture",args[2])
            .put("evidence_digest",request.evidenceDigest).put("request",new JSONObject(request.bodyJson)));
        try(JevTransport transport=new JevTransport(endpoint,null,4,"probe")) {
            transport.setSnapshotIdentity(ApeSnapshot.transportIdentity());
            JevTransport.Call call=transport.submit(id,request.bodyJson,timeout,Math.max(16384,bytes));
            if(call==null)throw new IOException("Preflight rejected");
            JevTransport.Result result=call.await();
            receipt.put("wait_ns",result.waitNanos()).put("latency_ns",result.latencyNanos()).put("http_status",result.httpStatus)
                .put("raw_response",result.raw==null?JSONObject.NULL:result.raw).put("error",result.error==null?JSONObject.NULL:result.error);
            if(result.error==null)receipt.put("validated_response",JevProtocol.fromProvider(result.raw,request).toJson()).put("status","PASS");
            else receipt.put("status","FAIL");
            Files.write(output.resolve("receipt.json"),(receipt.toString()+"\n").getBytes(StandardCharsets.UTF_8));
            System.out.println(receipt.getString("status")+" "+id);
            if(result.error!=null)System.exit(1);
        }
    }
    private ProbePreflight(){}
}
