/**
 * ValidateServlet
 * Copyright 05.08.2015 by Dang Hai An, @zyzo
 * <p/>
 * This library 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 2.1 of the License, or (at your option) any later version.
 * <p/>
 * This library 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
 * Lesser General Public License for more details.
 * <p/>
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program in the file lgpl21.txt
 * If not, see <http://www.gnu.org/licenses/>.
 */

package org.loklak.api.server;

import com.github.fge.jsonschema.core.report.ProcessingReport;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.loklak.api.client.ClientConnection;
import org.loklak.data.DAO;
import org.loklak.harvester.JsonValidator;
import org.loklak.harvester.SourceType;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

public class ValidateServlet extends HttpServlet {

    enum ValidationStatus {
        offline,
        invalid,
        valid
    }

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

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        RemoteAccess.Post post = RemoteAccess.evaluate(request);
        String remoteHash = Integer.toHexString(Math.abs(post.getClientHost().hashCode()));

        // manage DoS
        if (post.isDoS_blackout()) {
            response.sendError(503, "your request frequency is too high");
            return;
        }

        String url = post.get("url", "");
        if (url == null || url.length() == 0) {
            response.sendError(400, "your request does not contain an url to your data object");
            return;
        }

        String source_type_str = post.get("source_type", "");
        if (source_type_str == null || source_type_str.length() == 0) {
            response.sendError(400, "your request does not contain a source_type parameter");
            return;
        }
        SourceType sourceType;
        try {
            sourceType = SourceType.valueOf(source_type_str.toUpperCase());
        } catch (IllegalArgumentException e) {
            response.sendError(400, "Invalid source_type parameter : " + source_type_str);
            return;
        }
        JsonValidator.JsonSchemaEnum jsonSchemaEnum;
        try {
            jsonSchemaEnum = JsonValidator.JsonSchemaEnum.valueOf(sourceType);
        } catch (IllegalArgumentException e) {
            response.sendError(400, "Current version of /api/validate.json doesn't support this source type: " + source_type_str);
            return;
        }
        String callback = post.get("callback", "");
        boolean jsonp = callback != null && callback.length() > 0;

        ValidationStatus status = null;
        String message = "";

        Map<String, Object> map;

        boolean offline = false;

        byte[] jsonText = null;
        try {
            jsonText = ClientConnection.download(url);
            map = DAO.jsonMapper.readValue(jsonText, DAO.jsonTypeRef);
        } catch (Exception e) {
            message = "Error reading json file from url";
            status = ValidationStatus.offline;
            offline = true;
        }

        if (!offline) {
            JsonValidator validator = new JsonValidator(jsonSchemaEnum);
            // validation phase
            ProcessingReport report = validator.validate(new String(jsonText));
            if (!report.isSuccess()) {
                status = ValidationStatus.invalid;
                message = "json does not conform to schema : " + jsonSchemaEnum.name() + "\n" + report;
            } else {
                status = ValidationStatus.valid;
            }
        }

        post.setResponse(response, "application/javascript");

        // generate json
        XContentBuilder json = XContentFactory.jsonBuilder().prettyPrint().lfAtEnd();
        json.startObject();
        json.field("status", status.name());
        if (!(message.length() == 0))
            json.field("details", message);
        json.endObject();

        // write json
        ServletOutputStream sos = response.getOutputStream();
        if (jsonp) sos.print(callback + "(");
        sos.print(json.string());
        if (jsonp) sos.println(");");
        sos.println();

        DAO.log("Validated url " + url + ". Result = " + status.name());
    }
}

@@ -3497,42 +3497,8 @@
 %22;%0A%0A
-        Map%3CString, Object%3E map;%0A%0A
     
@@ -3542,23 +3542,22 @@
  byte%5B%5D 
-jsonTex
+conten
 t = null
@@ -3550,32 +3550,68 @@
 content = null;%0A
+        String contentToStr = null;%0A
         try %7B%0A  
@@ -3620,23 +3620,22 @@
         
-jsonTex
+conten
 t = Clie
@@ -3674,99 +3674,203 @@
     
-    map = DAO.jsonMapper.readValue(jsonText, DAO.jsonTypeRef);%0A        %7D catch (Exception e
+%7D catch (Exception e) %7B%0A            message = %22Error reading json file from url%22;%0A            status = ValidationStatus.offline;%0A            offline = true;%0A        %7D%0A%0A        if (content == null
 ) %7B%0A
@@ -4033,24 +4033,72 @@
 !offline) %7B%0A
+            contentToStr = new String(content);%0A
             
@@ -4162,40 +4162,8 @@
 m);%0A
-            // validation phase%0A
     
@@ -4219,28 +4219,20 @@
 ate(
-new String(jsonText)
+contentToStr
 );%0A 
@@ -4844,24 +4844,107 @@
 , message);%0A
+        if (contentToStr != null)%0A            json.field(%22content%22, contentToStr);%0A
         json

Add source file content to response