var express = require("express") , HTTPResult = require("../util/http-result") , cryptoken = require("../util/crypto-token") , etags = require("../util/etags") , _ = require('underscore') ; module.exports = function(couch,schema) { var exports = {}; var util = require('./util')(couch,schema); var responses = require('./responses')(couch,schema); var app = exports.app = express(); app.get('/', util.ensureMIME(util.JSON_MIME), function(req,res) { var qs = {reduce:false,include_docs:true}; var now = new Date().toISOString(); var hr; if ( 'current' in req.query ) { // we make the assumption that there will be fewer // runs with no or a future enddate than with a // startdate in the past, i.e. we assume fewer future // surveys are planned than past surveys are run. hr = couch.get('_design/surveyRuns/_view/by_end_date',{ query: {startkey:now,reduce:false,include_docs:true} }).handle({ '-1': _.identity, 200: function(result) { return _.filter( util.handleRowDocs(result), function(doc){ return !doc.startDate || doc.startDate <= now; }); }, default: util.handleUnknownResponse }); } else if ( 'future' in req.query ) { hr = couch.get('_design/surveyRuns/_view/by_start_date',{ query: {startkey:now,reduce:false,include_docs:true} }).handle({ '-1': _.identity, 200: util.handleRowDocs, default: util.handleUnknownResponse }); } else if ( 'past' in req.query ) { hr = couch.get('_design/surveyRuns/_view/by_end_date',{ query: {endkey:now,reduce:false,include_docs:true} }).handle({ '-1': _.identity, 200: util.handleRowDocs, default: util.handleUnknownResponse }); } else { hr = util.getDocumentsOfType('SurveyRun'); } hr.handle({'-1': util.handleException}) .handle(res.send.bind(res)); }); app.post('/', util.ensureMIME(util.JSON_MIME), function(req,res) { var doc = req.body; var hr; if ( !util.isDocPublished(doc.survey) ) { hr = new HTTPResult(400,{error:"Cannot run unpublished survey."}); } else { hr = cryptoken() .then(function(token) { doc.secret = token; return util.postDocument('SurveyRun',doc); }); } hr.handle({'-1': util.handleException}) .handle(res.send.bind(res)); }); app.get('/:id', util.ensureMIME(util.JSON_MIME), util.makeDocGet_id('SurveyRun')); app.put('/:id', util.ensureMIME(util.JSON_MIME), function (req,res) { var id = req.params.id; var doc = req.body; var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev); var hr; if ( !util.isDocPublished(doc.survey) ) { hr = new HTTPResult(400,{error:"Cannot run unpublished survey."}); } else if ( typeof doc.secret === 'undefined' ) { hr = cryptoken() .then(function(token) { doc.secret = token; return util.putDocument(id,rev,'SurveyRun',doc); }); } else { hr = util.putDocument(id,rev,'SurveyRun',doc); } hr.handle({'-1': util.handleException}) .handle(res.send.bind(res)); }); app.delete('/:id', util.ensureMIME(util.JSON_MIME), function(req,res) { var id = req.params.id; var doc = req.body; var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev); responses.getResponsesBySurveyRunId(id) .handle({ 200: function(responses) { if ( responses.length > 0 ) { return new HTTPResult(403,{error:"Cannot delete run that has responses."}); } else { return util.deleteDocument(id,rev); } } }) .handle({'-1': util.handleException}) .handle(res.send.bind(res)); }); app.get('/:id/responses', util.ensureMIME(util.JSON_MIME), function(req,res) { var id = req.params.id; responses.getResponsesBySurveyRunId(id) .handle({'-1': util.handleException}) .handle(res.send.bind(res)); }); app.get('/:id/responses.csv', util.ensureMIME(util.CSV_MIME), function(req, res) { var id = req.params.id; responses.getResponsesBySurveyRunId(id) .handle({ '-1': function(result) { util.handleException(result) .handle(res.send.bind(res)); }, 200: function(responses) { var answers = _.map(responses,function(response){ return response.answers; }); res.set({ 'Content-Disposition': 'attachment; filename=surveyRun-'+id+'-responses.csv' }); res.status(200); util.writeObjectsToCSVStream(answers, res); res.end(); }, default: res.send.bind(res) }); }); return exports; };