/*
 * 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.IOException;

import javax.servlet.ServletOutputStream;

import org.apache.jena.atlas.web.MediaType;
import org.apache.jena.atlas.web.TypedOutputStream;
import org.apache.jena.graph.Graph;
import org.apache.jena.riot.*;
import org.apache.jena.riot.web.HttpNames;
import org.apache.jena.shared.JenaException;
import org.apache.jena.sparql.core.DatasetGraph;

public class GSP_R extends GSP_Base {

    public GSP_R() {}

    @Override
    protected void doGet(HttpAction action) {
        if ( isQuads(action) )
            execGetQuads(action);
        else
            execGetGSP(action);
    }

    protected void execGetQuads(HttpAction action) {
        ActionLib.setCommonHeaders(action.response);
        MediaType mediaType = ActionLib.contentNegotationQuads(action);
        ServletOutputStream output;
        try { output = action.response.getOutputStream(); }
        catch (IOException ex) { ServletOps.errorOccurred(ex); output = null; }

        TypedOutputStream out = new TypedOutputStream(output, mediaType);
        Lang lang = RDFLanguages.contentTypeToLang(mediaType.getContentType());
        if ( lang == null )
            lang = RDFLanguages.TRIG;

        if ( action.verbose )
            action.log.info(format("[%d]   Get: Content-Type=%s, Charset=%s => %s", action.id,
                mediaType.getContentType(), mediaType.getCharset(), lang.getName()));
        if ( !RDFLanguages.isQuads(lang) )
            ServletOps.errorBadRequest("Not a quads format: " + mediaType);

        action.beginRead();
        try {
            DatasetGraph dsg = decideDataset(action);
            action.response.setHeader("Content-type", lang.getContentType().toHeaderString());
            // ActionLib.contentNegotationQuads above
            // RDF/XML is not a choice but this code is general.
            RDFFormat fmt =
                // Choose streaming.
                ( lang == Lang.RDFXML ) ? RDFFormat.RDFXML_PLAIN : RDFWriterRegistry.defaultSerialization(lang);
            try {
                RDFDataMgr.write(out, dsg, fmt);
            } catch (JenaException ex) {
                if ( fmt.getLang().equals(Lang.RDFXML) )
                    ServletOps.errorBadRequest("Failed to write output in RDF/XML: "+ex.getMessage());
                else
                    ServletOps.errorOccurred("Failed to write output: "+ex.getMessage(), ex);
            }
            ServletOps.success(action);
        } finally {
            action.endRead();
        }
    }

    protected void execGetGSP(HttpAction action) {
        ActionLib.setCommonHeaders(action.response);
        MediaType mediaType = ActionLib.contentNegotationRDF(action);

        ServletOutputStream output;
        try { output = action.response.getOutputStream(); }
        catch (IOException ex) { ServletOps.errorOccurred(ex); output = null; }

        TypedOutputStream out = new TypedOutputStream(output, mediaType);
        Lang lang = RDFLanguages.contentTypeToLang(mediaType.getContentType());

        action.beginRead();
        if ( action.verbose )
            action.log.info(format("[%d]   Get: Content-Type=%s, Charset=%s => %s",
                            action.id, mediaType.getContentType(), mediaType.getCharset(), lang.getName()));
        try {
            DatasetGraph dsg = decideDataset(action);
            GSPTarget target = determineTarget(dsg, action);
            if ( action.log.isDebugEnabled() )
                action.log.debug("GET->"+target);
            boolean exists = target.exists();
            if ( ! exists )
                ServletOps.errorNotFound("No such graph: <"+target.name+">");
            Graph g = target.graph();
            if ( ! target.isDefault && g.isEmpty() )
                ServletOps.errorNotFound("No such graph: <"+target.name+">");
            // If we want to set the Content-Length, we need to buffer.
            //response.setContentLength(??);
            String ct = lang.getContentType().toHeaderString();
            action.response.setContentType(ct);
            //Special case RDF/XML to be the plain (faster, less readable) form
            RDFFormat fmt =
                ( lang == Lang.RDFXML ) ? RDFFormat.RDFXML_PLAIN : RDFWriterRegistry.defaultSerialization(lang);
            try {
                RDFDataMgr.write(out, g, fmt);
            } catch (JenaException ex) {
                // Some RDF/XML data is unwritable. All we can do is pretend it's a bad
                // request (inappropriate content type).
                // Good news - this happens before any output for RDF/XML-ABBREV.
                if ( fmt.getLang().equals(Lang.RDFXML) )
                    ServletOps.errorBadRequest("Failed to write output in RDF/XML: "+ex.getMessage());
                else
                    ServletOps.errorOccurred("Failed to write output: "+ex.getMessage(), ex);
            }
            ServletOps.success(action);
        } finally { action.endRead(); }
    }

    @Override
    protected void doOptions(HttpAction action) {
        ActionLib.setCommonHeadersForOptions(action.response);
        action.response.setHeader(HttpNames.hAllow, "GET,HEAD,OPTIONS");
        ServletOps.success(action);
    }

    @Override
    protected void doHead(HttpAction action) {
        if ( isQuads(action) )
            execHeadQuads(action);
        else
            execHeadGSP(action);
    }

    protected void execHeadQuads(HttpAction action) {
        ActionLib.setCommonHeaders(action.response);
        MediaType mediaType = ActionLib.contentNegotationQuads(action);
        if ( action.verbose )
            action.log.info(format("[%d]   Head: Content-Type=%s", action.id, mediaType.getContentType()));
        ServletOps.success(action);
    }

    protected void execHeadGSP(HttpAction action) {
        ActionLib.setCommonHeaders(action.response);
        MediaType mediaType = ActionLib.contentNegotationRDF(action);
        if ( action.verbose )
            action.log.info(format("[%d]   Head: Content-Type=%s", action.id, mediaType.getContentType()));
        // Check graph not 404.
        action.beginRead();
        try {
            DatasetGraph dsg = decideDataset(action);
            GSPTarget target = determineTarget(dsg, action);
            if ( action.log.isDebugEnabled() )
                action.log.debug("HEAD->"+target);
            boolean exists = target.exists();
            if ( ! exists )
                ServletOps.errorNotFound("No such graph: <"+target.name+">");
            ServletOps.success(action);
        } finally { action.endRead(); }
    }

    @Override
    protected void doPost(HttpAction action)
    { ServletOps.errorMethodNotAllowed("POST : Read-only"); }

    @Override
    protected void doDelete(HttpAction action)
    { ServletOps.errorMethodNotAllowed("DELETE : Read-only"); }

    @Override
    protected void doPut(HttpAction action)
    { ServletOps.errorMethodNotAllowed("PUT : Read-only"); }

    @Override
    protected void doPatch(HttpAction action)
    { ServletOps.errorMethodNotAllowed("PATCH : Read-only"); }

}
