/**
 * BankingSDKService — Phase 2 CloudI external service.
 *
 * Wraps a vendor-supplied Java banking SDK (ISO 8583 or proprietary)
 * as a CloudI external service. The vendor maintains this JAR; MomentPay
 * only maintains this thin CloudI wrapper.
 *
 * Service path: /+/banking/sdk/  (handles any tenant)
 *
 * cloudi.conf entry (uncomment in config/cloudi.conf when ready):
 *   [{prefix,        "/+/banking/sdk/"},
 *    {file_path,     "/usr/bin/java"},
 *    {args,          "-cp /app/services/banking_sdk_java/target/banking-sdk.jar BankingSDKService"},
 *    {count_process, 1},
 *    {max_r,         3},
 *    {max_t,         30}
 *   ]
 */

import org.cloudi.API;
import org.json.JSONObject;

import java.util.logging.Logger;
import java.util.logging.Level;

public class BankingSDKService {

    private static final Logger logger =
        Logger.getLogger(BankingSDKService.class.getName());

    private final API api;

    // Vendor SDK client — initialised once, reused across requests
    // private final VendorBankingClient vendorClient;

    public BankingSDKService(int threadIndex) throws Exception {
        this.api = new API(threadIndex);
        // Initialise vendor SDK from environment variables (SR-06: no secrets in cloudi.conf)
        // String vendorUrl = System.getenv("VENDOR_BANKING_URL");
        // String apiKey    = System.getenv("VENDOR_BANKING_API_KEY");
        // this.vendorClient = new VendorBankingClient(vendorUrl, apiKey);
        logger.info("BankingSDKService initialised");
    }

    public void run() {
        try {
            // Matches /+/banking/sdk/ — "+" matches any tenant_id
            this.api.subscribe("+/banking/sdk/", this, "handleRequest");
            logger.info("BankingSDKService started, subscribing to +/banking/sdk/");
            this.api.poll();
        } catch (API.TerminateException e) {
            logger.info("BankingSDKService terminated cleanly");
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Service error: " + e.getMessage(), e);
        }
    }

    /**
     * Handle an incoming MW-Core request.
     * Called by CloudI runtime for each subscribed message.
     */
    public Object handleRequest(
        Integer requestType, String name, String pattern,
        byte[] requestInfo, byte[] request,
        Integer timeout, Byte priority,
        byte[] transId, com.ericsson.otp.erlang.OtpErlangPid pid
    ) {
        try {
            JSONObject payload = new JSONObject(new String(request));

            // Safe context fields from MW-Core only (trace_id, tenant_id — SR-04)
            JSONObject info = requestInfo != null
                ? new JSONObject(new String(requestInfo))
                : new JSONObject();
            String traceId  = info.optString("trace_id", "unknown");
            String tenantId = info.optString("tenant_id", "unknown");

            logger.info("Processing banking SDK request trace_id=" + traceId +
                        " tenant_id=" + tenantId);

            // Dispatch to vendor SDK
            Object result = process(payload, info);

            JSONObject response = new JSONObject();
            response.put("status", "ok");
            response.put("data", result);
            logger.info("Banking SDK request complete trace_id=" + traceId);
            return response.toString().getBytes();

        } catch (Exception e) {
            logger.log(Level.SEVERE, "Request failed: " + e.getMessage(), e);
            JSONObject error = new JSONObject();
            error.put("status", "error");
            error.put("reason", e.getMessage());
            return error.toString().getBytes();
        }
    }

    /**
     * Dispatch to the vendor banking SDK.
     *
     * Replace this stub with actual vendor SDK calls.
     * Example (ISO 8583 Java SDK):
     *   ISOMsg msg = vendorClient.buildRequest(payload);
     *   ISOMsg response = vendorClient.send(msg);
     *   return parseResponse(response);
     *
     * @param payload The deserialized MW-Core message payload
     * @param info    Context metadata (trace_id, tenant_id, etc.)
     * @return Result object to be JSON-serialized and returned to MW-Core
     */
    private Object process(JSONObject payload, JSONObject info) throws Exception {
        // TODO: Replace with vendor SDK invocation
        // Vendor SDK initialised in constructor from environment variables
        throw new UnsupportedOperationException(
            "Implement vendor banking SDK call here. " +
            "Vendor JAR is on the classpath. " +
            "Credentials are in environment variables VENDOR_BANKING_URL, VENDOR_BANKING_API_KEY."
        );
    }

    public static void main(String[] args) throws Exception {
        assert API.thread_count() == 1 : "Single-threaded service required";
        new BankingSDKService(0).run();
    }
}
