package com.r11.tools.controller;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.r11.tools.controller.internal.GlobalControllerManifest;
import com.r11.tools.controller.internal.HandlerType;
import com.r11.tools.controller.internal.RestController;
import com.r11.tools.controller.internal.ScopedControllerManifest;
import com.r11.tools.xml.Xalan;
import org.apache.logging.log4j.Logger;
import spark.Request;
import spark.Response;

@GlobalControllerManifest
public class XsdController implements RestController {

    private final Gson gson;
    private final Logger logger;

    public XsdController(Gson gson, Logger logger) {
        this.gson = gson;
        this.logger = logger;
    }

    @ScopedControllerManifest(method = HandlerType.POST, path = "/xsd")
    public Response transform(Request request, Response response) {
        String body = request.body();

        JsonObject requestJson;
        try {
            requestJson = this.gson.fromJson(body, JsonObject.class);
        } catch (Exception e) {
            JsonObject responseJson = new JsonObject();
            responseJson.addProperty("result", e.getMessage());
            responseJson.addProperty("processor", "N/A");
            responseJson.addProperty("status", "ERR");
            responseJson.addProperty("time", "N/A");

            response.status(400);
            response.body(this.gson.toJson(responseJson));
            return response;
        }

        String data = requestJson.get("data").getAsString();
        String xsd = requestJson.get("process").getAsString();

        response.header("processor", Xalan.getVersion());

        long timeStart = System.currentTimeMillis();
        String tmp;

        JsonObject responseJson = new JsonObject();
        try {
            tmp = Xalan.validate(data, xsd).trim();

            response.status(200);

            responseJson.addProperty("result", tmp);
            responseJson.addProperty("status", "OK");
        } catch (Exception ex) {
            this.logger.error("Error on validation against XSD using Xalan. " + ex);

            response.status(400);

            responseJson.addProperty("result", ex.getMessage());
            responseJson.addProperty("status", "ERR");
        }

        long duration = System.currentTimeMillis() - timeStart;
        this.logger.info("Request (XSD, Xalan) processed in " + duration + " ms.");

        responseJson.addProperty("processor", Xalan.getVersion());
        responseJson.addProperty("time", duration);

        response.body(this.gson.toJson(responseJson));
        return response;
    }
}
