/* global LocusZoom,Q */
/* eslint-env browser */
/* eslint-disable no-console */

"use strict";

LocusZoom.Data = LocusZoom.Data ||  {};

LocusZoom.Data.Requester = function(sources) {

    function split_requests(fields) {
        var requests = {};
        fields.forEach(function(field) {
            var parts = field.split(/\:(.*)/);
            if (parts.length==1) {
                if (typeof requests["base"] == "undefined") {
                    requests.base = [];
                }
                requests.base.push(field);
            } else {
                if (typeof requests[parts[0]] =="undefined") {
                    requests[parts[0]] = [];
                }
                requests[parts[0]].push(parts[1]);
            }
        });
        return requests;
    }
    
    this.getData = function(state, fields) {
        var requests = split_requests(fields);
        var promises = Object.keys(requests).map(function(key) {
            return sources[key].getData(state, requests[key]);
        });
        //assume the are requested in dependent order
        //TODO: better manage dependencies
        var ret = Q.when({});
        for(var i=0; i < promises.length; i++) {
            ret = ret.then(promises[i]);
        }
        return ret;
    };
};

LocusZoom.Data.AssociationSource = function(url) {
    this.url = url;

    this.getData = function(state, fields) {
        ["id","position"].forEach(function(x) {
            if (fields.indexOf(x)==-1) {
                fields.unshift(x);
            }
        });
        return function (chain) {
            var requrl = url + "results?filter=analysis in 1 " + 
                "and chromosome in  '" + state.chr + "'" + 
                " and position ge " + state.start + 
                " and position le " + state.end;
            return LocusZoom.createCORSPromise("GET",requrl).then(function(x) {
                var records = [];
                fields.forEach(function(f) {
                    if (!(f in x)) {throw "field " + f + " not found in response";}
                });
                for(var i = 0; i < x.position.length; i++) {
                    var record = {};
                    fields.forEach(function(f) {
                        record[f] = x[f][i];
                    });
                    records.push(record);
                }
                var res = {header: chain.header, body: records};
                return res;
            });
        };
    };
};

LocusZoom.Data.LDSource = function(url) {
    this.url = url;

    var findSmallestPvalue = function(x, pval) {
        pval = pval || "pvalue";
        var smVal = x[0][pval], smIdx=0;
        for(var i=1; i<x.length; i++) {
            if (x[i][pval] < smVal) {
                smVal = x[i][pval];
                smIdx = i;
            }
        }
        return smIdx;
    };

    this.getData = function(state, fields) {
        return function (chain) {
            var refVar = state.ldrefvar || chain.header.ldrefvar;
            if (!refVar) {
                refVar = chain.body[findSmallestPvalue(chain.body)].id;
            }
            var requrl = url + "results?find=reference::2" + 
                "|chr::" + state.chr + 
                "|start::" + state.start + 
                "|end::" + state.end + 
                "|id1::" + refVar + 
                "&fields=chr,pos,rsquare";
            return LocusZoom.createCORSPromise("GET",requrl).then(function(x) {
                chain.header.ldrefvar = refVar;
                console.log(x);
                return chain;   
            });
        };
    };
};

LocusZoom.Data.GeneSource = function(url) {
    this.url = url;

    this.getData = function(state, fields) {
        return function (chain) {
            var requrl = url + "?filter=source eq 1" + 
                " and chrom eq " + state.chr + 
                " and start ge " + state.start + 
                " and end le " + state.end;
            return LocusZoom.createCORSPromise("GET",requrl).then(function(x) {
                return {header: chain.header, body: x.data};
            }, function(err) {
                console.log(err);
            });
        };
    };
};

LocusZoom.createResolvedPromise = function() {
    var response = Q.defer();
    response.resolve(Array.prototype.slice.call(arguments));
    return response.promise;
};

LocusZoom.DefaultDataSources = {
    base: new LocusZoom.Data.AssociationSource("/api/v1/single/"),
    ld: new LocusZoom.Data.LDSource("/api/v1/pair/LD/"),
    gene: new LocusZoom.Data.GeneSource("/api/v1/annotation/genes/")
};

var lzd = new LocusZoom.Data.Requester(LocusZoom.DefaultDataSources);

@@ -1621,16 +1621,17 @@
 %22results
+/
 ?filter=
@@ -1645,24 +1645,24 @@
 s in 1 %22 + %0A
-
             
@@ -2389,32 +2389,38 @@
 er: chain.header
+ %7C%7C %7B%7D
 , body: records%7D
@@ -3169,13 +3169,16 @@
 ults
+/
 ?fi
-nd
+lter
 =ref
@@ -3183,18 +3183,20 @@
 eference
-::
+ eq 
 2%22 + %0A  
@@ -3214,14 +3214,29 @@
    %22
-%7Cchr::
+ and chromosome2 eq '
 %22 + 
@@ -3239,32 +3239,38 @@
 %22 + state.chr + 
+%22'%22 + 
 %0A               
@@ -3275,16 +3275,26 @@
    %22
-%7Cstart::
+ and position2 ge 
 %22 + 
@@ -3329,14 +3329,26 @@
    %22
-%7Cend::
+ and position2 le 
 %22 + 
@@ -3381,14 +3381,26 @@
    %22
-%7Cid1::
+ and variant1 eq '
 %22 + 
@@ -3404,24 +3404,30 @@
  + refVar + 
+%22'%22 + 
 %0A           
@@ -3880,18 +3880,18 @@
 =source 
-eq
+in
  1%22 + %0A 
@@ -3920,16 +3920,17 @@
 hrom eq 
+'
 %22 + stat
@@ -3937,16 +3937,22 @@
 e.chr + 
+%22'%22 + 
 %0A       

Update API endpoints to new syntax