/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jena.fuseki.servlets;

import static java.lang.String.format;

import java.io.PrintWriter;

import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.jena.fuseki.Fuseki;
import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.fuseki.system.Upload;
import org.apache.jena.fuseki.system.UploadDetailsWithName;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.NodeFactory;
import org.apache.jena.riot.web.HttpNames;
import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.sparql.core.Quad;
import org.apache.jena.web.HttpSC;

/**
 * Upload data into a graph within a dataset. This is {@code fuseki:serviceUpload}.
 *
 * It is better to use GSP or quads POST with the body being the content.
 *
 * This class works with general HTML form file upload where the name is somewhere in the form and that may be
 * after the data.
 *
 * Consider this service useful for small files and use GSP or quads POST for large ones.
 */
public class SPARQL_Upload extends ActionService
{
    public SPARQL_Upload() {
        super();
    }

    @Override
    public void execPost(HttpAction action) {
        executeLifecycle(action);
    }

    @Override
    public void execOptions(HttpAction action) {
        ServletBase.setCommonHeadersForOptions(action.response);
        action.response.setHeader(HttpNames.hAllow, "POST,PATCH,OPTIONS");
        ServletOps.success(action);
    }

    @Override
    public void validate(HttpAction action)
    {}

    @Override
    public void execute(HttpAction action) {

        // Only allows one file in the upload.
        boolean isMultipart = ServletFileUpload.isMultipartContent(action.request);
        if ( ! isMultipart )
            ServletOps.error(HttpSC.BAD_REQUEST_400 , "Not a file upload");

        long count = upload(action, Fuseki.BaseUpload);
        ServletOps.success(action);
        try {
            action.response.setContentType("text/html");
            action.response.setStatus(HttpSC.OK_200);
            PrintWriter out = action.response.getWriter();
            out.println("<html>");
            out.println("<head>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Success</h1>");
            out.println("<p>");
            out.println("Triples = "+count + "\n");
            out.println("<p>");
            out.println("</p>");
            out.println("<button onclick=\"timeFunction()\">Back to Fuseki</button>");
            out.println("</p>");
            out.println("<script type=\"text/javascript\">");
            out.println("function timeFunction(){");
            out.println("window.location.href = \"/fuseki.html\";}");
            out.println("</script>");
            out.println("</body>");
            out.println("</html>");
            out.flush();
            ServletOps.success(action);
        }
        catch (Exception ex) { ServletOps.errorOccurred(ex); }
    }

    // Also used by SPARQL_REST
    static public long upload(HttpAction action, String base) {
        if ( action.isTransactional() )
            return uploadTxn(action, base);
        else
            return uploadNonTxn(action, base);
    }

    /** 
     * Non-transaction - buffer to a temporary graph so that parse errors
     * are caught before inserting any data.
     */
    private static long uploadNonTxn(HttpAction action, String base) {
        UploadDetailsWithName upload = Upload.multipartUploadWorker(action, base);
        String graphName = upload.graphName;
        DatasetGraph dataTmp = upload.data;
        long count = upload.count;

        if ( graphName == null )
            action.log.info(format("[%d] Upload: %d Quads(s)",action.id, count));
        else
            action.log.info(format("[%d] Upload: Graph: %s, %d triple(s)", action.id, graphName,  count));

        Node gn = null;
        if ( graphName != null ) {
            gn = graphName.equals(HttpNames.graphTargetDefault)
                ? Quad.defaultGraphNodeGenerated
                : NodeFactory.createURI(graphName);
        }

        action.beginWrite();
        try {
            if ( gn != null )
                FusekiNetLib.addDataInto(dataTmp.getDefaultGraph(), action.getActiveDSG(), gn);
            else
                FusekiNetLib.addDataInto(dataTmp, action.getActiveDSG());
            action.commit();
            return count;
        } catch (RuntimeException ex) {
            // If anything went wrong, try to backout.
            try { action.abort(); } catch (Exception ex2) {}
            ServletOps.errorOccurred(ex.getMessage());
            return -1;
        }
        finally { action.end(); }
    }

    /**
     * Transactional - we'd like better handle the data and go straight to the destination, with an abort on parse error.
     * For an HTML file upload that's not so simple in the general case.
     * Use Graph Store protocol for bulk uploads.
     */
    private static long uploadTxn(HttpAction action, String base) {
        return uploadNonTxn(action, base);
    }

}
