/**
 * Java CloudI external service template.
 *
 * Copy this file to services/[your_service_name]/src/main/java/ServiceNameService.java
 * and:
 * 1. Replace ServiceName with your service class name
 * 2. Replace [tenant_pattern]/[service_path] with the actual CloudI service path
 * 3. Implement process() with your vendor SDK logic
 * 4. Add vendor JAR dependencies to pom.xml
 * 5. Add a cloudi.conf entry in config/cloudi.conf
 *
 * Subscribe path pattern: /{tenant_id}/{service_path}
 * Use "+/" CloudI wildcard to match any tenant.
 */

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

import java.util.logging.Logger;

public class ServiceNameService {

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

    private final API api;

    public ServiceNameService(int threadIndex) throws Exception {
        this.api = new API(threadIndex);
    }

    public void run() {
        try {
            // Subscribe path must match ServiceResolver output in adapter_cloudi
            // Pattern: /{tenant_id}/{service_path} — use "+/" to match any tenant
            this.api.subscribe("+/service/path", this, "handleRequest");
            logger.info("Service started, waiting for requests");
            this.api.poll();
        } catch (API.TerminateException e) {
            logger.info("Service terminated cleanly");
        } catch (Exception e) {
            logger.severe("Service error: " + e.getMessage());
        }
    }

    /**
     * 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 (trace_id, tenant_id only — 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 request trace_id=" + traceId +
                        " tenant_id=" + tenantId);

            // --- YOUR VENDOR SDK LOGIC HERE ---
            Object result = process(payload, info);
            // ----------------------------------

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

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

    /**
     * Implement vendor SDK logic here.
     * Full Java ecosystem available: vendor JARs, Spring, Jackson, etc.
     *
     * @param payload The deserialized MW-Core message payload
     * @param info    Context metadata (trace_id, tenant_id, message_type, etc.)
     * @return Result object to be JSON-serialized and returned to MW-Core
     */
    private Object process(JSONObject payload, JSONObject info) throws Exception {
        throw new UnsupportedOperationException("Implement vendor logic here");
    }

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