package org.intermine.bio.webservice;

import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.intermine.api.InterMineAPI;
import org.intermine.api.profile.Profile;
import org.intermine.api.query.PathQueryExecutor;
import org.intermine.api.results.ExportResultsIterator;
import org.intermine.bio.web.export.SequenceExporter;
import org.intermine.objectstore.ObjectStore;
import org.intermine.pathquery.PathQuery;
import org.intermine.util.StringUtil;
import org.intermine.web.logic.export.Exporter;
import org.intermine.web.logic.export.ResponseUtil;
import org.intermine.web.logic.session.SessionMethods;
import org.intermine.webservice.server.WebServiceRequestParser;
import org.intermine.webservice.server.exceptions.BadRequestException;
import org.intermine.webservice.server.exceptions.InternalErrorException;
import org.intermine.webservice.server.output.Output;
import org.intermine.webservice.server.output.StreamedOutput;
import org.intermine.webservice.server.output.TabFormatter;
import org.intermine.webservice.server.query.AbstractQueryService;
import org.intermine.webservice.server.query.result.PathQueryBuilder;

/**
 * A service for exporting query results as fasta.
 * @author Alexis Kalderimis.
 *
 */
public class FastaQueryService extends AbstractQueryService
{

    private static final String XML_PARAM = "query";

    /**
     * Constructor.
     * @param im A reference to an InterMine API settings bundle.
     */
    public FastaQueryService(InterMineAPI im) {
        super(im);
    }

    @Override
    protected String getDefaultFileName() {
        return "results" + StringUtil.uniqueString() + ".fa";
    }

    protected OutputStream os;

    @Override
    protected Output getDefaultOutput(PrintWriter out, OutputStream os, String sep) {
        this.os = os;
        output = new StreamedOutput(out, new TabFormatter(), sep);
        if (isUncompressed()) {
            ResponseUtil.setPlainTextHeader(response,
                    getDefaultFileName());
        }
        return output;
    }

    @Override
    public int getFormat() {
        return UNKNOWN_FORMAT;
    }

    @Override
    protected void execute() throws Exception {
        HttpSession session = request.getSession();

        PathQuery pathQuery = getQuery();
        int index = 0;

        Exporter exporter;
        try {
            ObjectStore objStore = im.getObjectStore();
            exporter = new SequenceExporter(objStore, os, index, im.getClassKeys());
            ExportResultsIterator iter = null;
            try {
                Profile profile = SessionMethods.getProfile(session);
                PathQueryExecutor executor = this.im.getPathQueryExecutor(profile);
                iter = executor.execute(pathQuery, 0, WebServiceRequestParser.DEFAULT_MAX_COUNT);
                iter.goFaster();
                exporter.export(iter);
            } finally {
                if (iter != null) {
                    iter.releaseGoFaster();
                }
            }
        } catch (Exception e) {
            throw new InternalErrorException("Service failed:" + e, e);
        }

    }


    /**
     * Return the query specified in the request, shorn of all duplicate
     * classes in the view. Note, it is the users responsibility to ensure
     * that there are only SequenceFeatures in the view.
     * @return A suitable pathquery for getting GFF3 data from.
     */
    protected PathQuery getQuery() {
        String xml = request.getParameter(XML_PARAM);

        if (StringUtils.isEmpty(xml)) {
            throw new BadRequestException("query is blank");
        }

        PathQueryBuilder builder = getQueryBuilder(xml);
        PathQuery pq = builder.getQuery();

        if (pq.getView().size() > 1) {
            throw new BadRequestException(
                    "Queries for this webservice may only have one output column");
        }

        return pq;
    }

}

@@ -897,32 +897,109 @@
 ErrorException;%0A
+import org.intermine.webservice.server.exceptions.MissingParameterException;%0A
 import org.inter
@@ -2353,94 +2353,800 @@
     
-HttpSession session = request.getSession();%0A
+Profile profile = getPermission().getProfile();%0A        %0A        final String xml = request.getParameter(XML_PARAM);%0A        if (StringUtils.isBlank(xml)) %7B%0A            throw new MissingParameterException(XML_PARAM);%0A        %7D%0A        PathQuery pathQuery = getQuery(xml);%0A%0A        final String extension = request.getParameter(%22extension%22);%0A        %0A        if (StringUtils.isBlank(extension)) %7B%0A            exportFasta(profile, pathQuery);%0A        %7D else %7B%0A            exportFastaWithExtension(profile, pathQuery, extension);%0A        %7D
 %0A    
+%7D%0A%0A
     
-PathQuery pathQuery = getQuery();
+private void exportFastaWithExtension(final Profile profile, final PathQuery pathQuery, final String extension) %7B%0A        // TODO Auto-generated method stub%0A    %7D%0A%0A    private void exportFasta(final Profile profile, final PathQuery pathQuery) %7B
 %0A   
@@ -3417,78 +3417,8 @@
 y %7B%0A
-                Profile profile = SessionMethods.getProfile(session);%0A
     
@@ -3913,25 +3913,24 @@
 ;%0A        %7D%0A
-%0A
     %7D%0A%0A%0A    
@@ -4247,104 +4247,25 @@
 ery(
-) %7B%0A        String xml = request.getParameter(XML_PARAM);%0A%0A        if (StringUtils.isEmpty(
+final String 
 xml)
-)
  %7B%0A 
@@ -4275,71 +4275,8 @@
     
-    throw new BadRequestException(%22query is blank%22);%0A        %7D%0A
 %0A   

Stubbed out the extensionality of the query