/*-
 * #%L
 * This file is part of "Apromore Community".
 *
 * Copyright (C) 2015 - 2017 Queensland University of Technology.
 * Copyright (C) 2016 Adriano Augusto.
 * %%
 * Copyright (C) 2018 - 2020 The University of Melbourne.
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
 * #L%
 */

package org.apromore.plugin.editor.metrics2;

// Java 2 Standard
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;

// Java 2 Enterprise
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;

// Third party
import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.springframework.web.context.support.WebApplicationContextUtils;

// Apromore
import de.hpi.bpmn2_0.factory.AbstractBpmnFactory;
import de.hpi.bpmn2_0.model.Definitions;
import de.hpi.bpmn2_0.model.extension.synergia.Configurable;
import de.hpi.bpmn2_0.model.extension.synergia.ConfigurationAnnotationAssociation;
import de.hpi.bpmn2_0.model.extension.synergia.ConfigurationAnnotationShape;
import de.hpi.bpmn2_0.model.extension.synergia.Variants;
import de.hpi.bpmn2_0.transformation.Diagram2BpmnConverter;

import org.apromore.processmining.models.graphbased.directed.bpmn.BPMNDiagram;
import org.apromore.service.bpmndiagramimporter.BPMNDiagramImporter;
import org.apromore.service.metrics.MetricsService;
import org.oryxeditor.server.diagram.basic.BasicDiagram;
import org.oryxeditor.server.diagram.basic.BasicDiagramBuilder;


public class MetricsServlet extends HttpServlet {

    private static final Logger LOGGER = Logger.getLogger(MetricsServlet.class);

    private BPMNDiagramImporter importerService;
    private MetricsService metricsService;

    public void init(ServletConfig config) throws ServletException {
        importerService = (BPMNDiagramImporter)
            WebApplicationContextUtils.getWebApplicationContext(config.getServletContext())
                                      .getAutowireCapableBeanFactory()
                                      .getBean("importerService");
        metricsService = (MetricsService)
            WebApplicationContextUtils.getWebApplicationContext(config.getServletContext())
                                      .getAutowireCapableBeanFactory()
                                      .getBean("metricsService");
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        doPost(request, response);
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        String bpmnXML = request.getParameter("data");
        String diagramType = request.getParameter("type");

        /* Transform and return */
        try {
            if (bpmnXML == null || bpmnXML.isEmpty()) {
                response.setStatus(500);
                response.setContentType("text/plain; charset=UTF-8");
                response.getWriter().write("Empty or missing parameter 'data'!");
            } else {
                String metrics = compute(bpmnXML);
                response.setContentType("application/json");
                response.setStatus(200);
                response.getWriter().write(metrics);
            }
        } catch (Exception e) {
            try {
                LOGGER.error("Measurement failed: " + e.toString(), e);
                JSONObject json = new JSONObject();
                json.put("errors", e.toString());
                response.setStatus(500);
                response.setContentType("text/plain; charset=UTF-8");
            } catch (Exception e1) {
                LOGGER.error("Unable to report servlet error to JSON: " + e1.toString(), e1);
            }
        }
    }


    private String compute(String bpmnXML) throws Exception {
        BPMNDiagram bpmnDiagram = importerService.importBPMNDiagram(bpmnXML);

        /* result already in json format */
        Map<String, String> metrics = metricsService.computeMetrics(bpmnDiagram, true, true, true, true, true, true, true, true, true);

        JSONObject result = new JSONObject();

        for (String key : metrics.keySet()) {
            LOGGER.info(key + " : " + metrics.get(key));
            result.put(key, metrics.get(key));
        }
        LOGGER.info("metrics: " + metrics);

        return result.toString();
    }

}
