/*
 * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
 *
 * Licensed 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.zest.library.rest.admin;

import info.aduna.xml.XMLWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import org.openrdf.http.protocol.Protocol;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.query.*;
import org.openrdf.query.impl.DatasetImpl;
import org.openrdf.query.resultio.TupleQueryResultWriter;
import org.openrdf.query.resultio.sparqljson.SPARQLResultsJSONWriterFactory;
import org.openrdf.query.resultio.sparqlxml.SPARQLResultsXMLWriter;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.apache.zest.api.injection.scope.Service;
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Status;
import org.restlet.representation.InputRepresentation;
import org.restlet.representation.OutputRepresentation;
import org.restlet.representation.Representation;
import org.restlet.representation.Variant;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;

import static org.openrdf.http.protocol.Protocol.*;

/**
 * JAVADOC
 */
public class SPARQLResource
    extends ServerResource
{
    @Service
    Repository repository;

    public SPARQLResource()
    {
        getVariants().addAll( Arrays.asList(
            new Variant( MediaType.TEXT_HTML ),
            new Variant( MediaType.APPLICATION_RDF_XML ),
            new Variant( RestApplication.APPLICATION_SPARQL_JSON ) ) );
        setNegotiated( true );
    }

    @Override
    protected void doInit()
        throws ResourceException
    {
        super.doInit();
    }

    @Override
    public Representation get( final Variant variant )
        throws ResourceException
    {
        try
        {
            // TODO There's probably a helper somewhere that can do this more nicely
            if( getRequest().getOriginalRef().getLastSegment().equals( "sparqlhtml.xsl" ) )
            {
                InputStream resourceAsStream = getClass().getResourceAsStream( "sparqlhtml.xsl" );
                return new InputRepresentation( resourceAsStream, MediaType.TEXT_XML );
            }

            Form form;
            if( getRequest().getMethod().equals( Method.POST ) )
            {
                form = new Form(getRequest().getEntity());
            }
            else
            {
                form = getRequest().getResourceRef().getQueryAsForm();
            }

            final RepositoryConnection conn = repository.getConnection();

            String queryStr = form.getFirstValue( "query" );

            if( queryStr == null )
            {
                InputStream resourceAsStream = getClass().getResourceAsStream( "sparqlform.html" );
                return new InputRepresentation( resourceAsStream, MediaType.TEXT_HTML );
            }

            Query query = getQuery( repository, conn, queryStr );

            if( query instanceof TupleQuery )
            {
                TupleQuery tQuery = (TupleQuery) query;

                final TupleQueryResult queryResult = tQuery.evaluate();

                if( variant.getMediaType().equals( MediaType.TEXT_HTML ) )
                {
                    return new OutputRepresentation( MediaType.TEXT_XML )
                    {
                        @Override
                        public void write( OutputStream outputStream )
                            throws IOException
                        {
                            try
                            {
                                PrintWriter out = new PrintWriter( outputStream );
                                out.println( "<?xml version='1.0' encoding='UTF-8'?>" );
                                out.println( "<?xml-stylesheet type=\"text/xsl\" href=\"query/sparqlhtml.xsl\"?>" );
                                out.flush();
                                TupleQueryResultWriter qrWriter = new SPARQLResultsXMLWriter( new XMLWriter( outputStream )
                                {
                                    @Override
                                    public void startDocument()
                                        throws IOException
                                    {
                                        // Ignore
                                    }
                                } );
                                QueryResultUtil.report( queryResult, qrWriter );
                            }
                            catch( Exception e )
                            {
                                throw new IOException( e );
                            }
                            finally
                            {
                                try
                                {
                                    conn.close();
                                }
                                catch( RepositoryException e )
                                {
                                    // Ignore
                                }
                            }
                        }
                    };
                }
                else if( variant.getMediaType().equals( MediaType.APPLICATION_RDF_XML ) )
                {
                    return new OutputRepresentation( MediaType.APPLICATION_XML )
                    {
                        @Override
                        public void write( OutputStream outputStream )
                            throws IOException
                        {
                            try
                            {
                                TupleQueryResultWriter qrWriter = new SPARQLResultsXMLWriter( new XMLWriter( outputStream ) );
                                QueryResultUtil.report( queryResult, qrWriter );
                            }
                            catch( Exception e )
                            {
                                throw new IOException( e );
                            }
                            finally
                            {
                                try
                                {
                                    conn.close();
                                }
                                catch( RepositoryException e )
                                {
                                    // Ignore
                                }
                            }
                        }
                    };
                }
                else if( variant.getMediaType().equals( RestApplication.APPLICATION_SPARQL_JSON ) )
                {
                    return new OutputRepresentation( RestApplication.APPLICATION_SPARQL_JSON )
                    {
                        @Override
                        public void write( OutputStream outputStream )
                            throws IOException
                        {
                            try
                            {
                                TupleQueryResultWriter qrWriter = new SPARQLResultsJSONWriterFactory().getWriter( outputStream );
                                QueryResultUtil.report( queryResult, qrWriter );
                            }
                            catch( Exception e )
                            {
                                throw new IOException( e );
                            }
                            finally
                            {
                                try
                                {
                                    conn.close();
                                }
                                catch( RepositoryException e )
                                {
                                    // Ignore
                                }
                            }
                        }
                    };
                }
            }
            else if( query instanceof GraphQuery )
            {
                GraphQuery gQuery = (GraphQuery) query;

                /*
                                queryResult = gQuery.evaluate();
                                registry = RDFWriterRegistry.getInstance();
                                view = GraphQueryResultView.getInstance();
                */
                conn.close();
            }
            else if( query instanceof BooleanQuery )
            {
                BooleanQuery bQuery = (BooleanQuery) query;

                /*
                                queryResult = bQuery.evaluate();
                                registry = BooleanQueryResultWriterRegistry.getInstance();
                                view = BooleanQueryResultView.getInstance();
                */
                conn.close();
            }
            else
            {
                conn.close();
                throw new ResourceException( Status.CLIENT_ERROR_BAD_REQUEST, "Unsupported query type: "
                                                                              + query.getClass().getName() );
            }
        }
        catch( RepositoryException e )
        {
            throw new ResourceException( Status.SERVER_ERROR_INTERNAL, e );
        }
        catch( QueryEvaluationException e )
        {
            throw new ResourceException( Status.SERVER_ERROR_INTERNAL, e );
        }

        return null;
    }

    private Query getQuery( Repository repository, RepositoryConnection repositoryCon, String queryStr
    )
        throws ResourceException
    {
        Form form = getRequest().getResourceRef().getQueryAsForm();

        Query result;

// default query language is SPARQL
        QueryLanguage queryLn = QueryLanguage.SPARQL;

// determine if inferred triples should be included in query evaluation
        boolean includeInferred = true;

// build a dataset, if specified
        String[] defaultGraphURIs = form.getValuesArray( DEFAULT_GRAPH_PARAM_NAME );
        String[] namedGraphURIs = form.getValuesArray( NAMED_GRAPH_PARAM_NAME );

        DatasetImpl dataset = null;
        if( defaultGraphURIs.length > 0 || namedGraphURIs.length > 0 )
        {
            dataset = new DatasetImpl();

            if( defaultGraphURIs.length > 0 )
            {
                for( String defaultGraphURI : defaultGraphURIs )
                {
                    try
                    {
                        URI uri = repository.getValueFactory().createURI( defaultGraphURI );
                        dataset.addDefaultGraph( uri );
                    }
                    catch( IllegalArgumentException e )
                    {
                        throw new ResourceException( Status.CLIENT_ERROR_BAD_REQUEST, "Illegal URI for default graph: "
                                                                                      + defaultGraphURI );
                    }
                }
            }

            if( namedGraphURIs.length > 0 )
            {
                for( String namedGraphURI : namedGraphURIs )
                {
                    try
                    {
                        URI uri = repository.getValueFactory().createURI( namedGraphURI );
                        dataset.addNamedGraph( uri );
                    }
                    catch( IllegalArgumentException e )
                    {
                        throw new ResourceException( Status.CLIENT_ERROR_BAD_REQUEST, "Illegal URI for named graph: "
                                                                                      + namedGraphURI );
                    }
                }
            }
        }

        try
        {
            result = repositoryCon.prepareQuery( queryLn, queryStr );
            result.setIncludeInferred( includeInferred );

            if( dataset != null )
            {
                result.setDataset( dataset );
            }

// determine if any variable bindings have been set on this query.
            @SuppressWarnings( "unchecked" )
            Enumeration<String> parameterNames = Collections.enumeration( form.getValuesMap().keySet() );

            while( parameterNames.hasMoreElements() )
            {
                String parameterName = parameterNames.nextElement();

                if( parameterName.startsWith( BINDING_PREFIX ) && parameterName.length() > BINDING_PREFIX.length() )
                {
                    String bindingName = parameterName.substring( BINDING_PREFIX.length() );
                    Value bindingValue = parseValueParam( repository, form, parameterName );
                    result.setBinding( bindingName, bindingValue );
                }
            }
        }
        catch( UnsupportedQueryLanguageException e )
        {
            throw new ResourceException( Status.CLIENT_ERROR_BAD_REQUEST, e.getMessage() );
        }
        catch( MalformedQueryException e )
        {
            throw new ResourceException( Status.CLIENT_ERROR_BAD_REQUEST, e.getMessage() );
        }
        catch( RepositoryException e )
        {
            throw new ResourceException( Status.SERVER_ERROR_INTERNAL, e.getMessage() );
        }

        return result;
    }

    private Value parseValueParam( Repository repository, Form form, String parameterName )
        throws ResourceException
    {
        String paramValue = form.getFirstValue( parameterName );
        try
        {
            return Protocol.decodeValue( paramValue, repository.getValueFactory() );
        }
        catch( IllegalArgumentException e )
        {
            throw new ResourceException( Status.CLIENT_ERROR_BAD_REQUEST, "Invalid value for parameter '" + parameterName + "': "
                                                                          + paramValue );
        }
    }
}
