var Q = require('q');
var pyrusConnectClinical = require('./pyrusConnectClinical');
var httpMocks = require('node-mocks-http');
var urlParser = require('url');
var fs = require('fs');

function createReq(url) {
    var req = httpMocks.createRequest({
        method: 'GET',
        url: url
    });

    // Express will derive req.params from url
    req.params = {};
    var ref = url.toLowerCase().split('/')[2];
    var val = url.split('/')[3];
    req.params['org'] = url.split('/')[1];
    req.params[ref] = val;

    // Express will derive req.query from url
    var query = url.match(/(Patient|Slot|Schedule|Appointment)\?((identifier|birthdate|name|schedule|date).*)/);
    if (query) {
        req.query = {};
        var searchTerms = query[2].split('&');
        searchTerms.forEach( function(item) {
           var term = item.split('=')[0];
            req.query[term] = item.split('=')[1];
        });
    }

    return req;

}

function decorateReq(req) {
    function getOrganisation(orgCode) {
        organisations = {
            "Z99998": {
                "connectionString": "emisWebHost=127.0.0.1;organisation=MADEVD1;productId=88796c07-e0b0-4979-bc28-35962820f93a;user=Blackpear;password=Black123",
                "email": "bptest@blackpear.com"
            },
            "Z99999": {
                "connectionString": "emisWebHost=185.13.72.18;organisation=50002;productId=88796c07-e0b0-4979-bc28-35962820f93a;user=Blackpear;password=Black123",
                "email": "bptest@blackpear.com"
            },
            "Z99997": {
                "connectionString": "adapter=mock;id=Z99997"
            },
            "UCC001": {
                "connectionString": "adapter=mock;id=UCC001;organisation=50002"
            },
            "Z99996": {
                "connectionString": "adapter=InpsVision;Name=MIGSoap;Address=https://dev.inpses.co.uk:443/vmas/MIG;MaxReceivedMessageSize=2;user=bpuser@nhs.net;password=password2"
            }
        };

        if (organisations[orgCode])
            return organisations[orgCode];
        else
            throw new Error;
    }

    function removeOrgFromQuery() {

        var tmpUrl = urlParser.parse(req.url, true);
        delete tmpUrl.query.organization;
        tmpUrl.search = null;
        return decodeURIComponent(urlParser.format(tmpUrl));
    }

    function removeOrgFromPath() {
        return req.url.substring(orgCode.length + 1)
    }

    var orgCode = req.params.org || req.query['organization'];


    req.organisation = getOrganisation(orgCode);

    req.pyrusUrl = (req.params.org)
        ? removeOrgFromPath()
        : removeOrgFromQuery();

}

function fixNhsIdentifier(originalUrl){

    //todo: change clinical system adapters to use actual identifier type rather than assume NHS|
    var tmpUrl = urlParser.parse(originalUrl, true);
    var id = tmpUrl.query['identifier'];
    if ((originalUrl.indexOf('/Patient?' == 0)) && (id) && (id.indexOf("|") == -1)){
        tmpUrl.query.identifier = "NHS|" + id;
    }
    tmpUrl.search = null;
    return decodeURIComponent(urlParser.format(tmpUrl));
}

function pyrusConnect(){

    function generateOperationOutcome(err, method, url) {
        err.status = 404;
        err.method = method;
        err.path = url;
        err.body = {
            "resourceType": "OperationOutcome",
            "issue": [
                {
                    "severity": "error",
                    "code": "processing",
                    "details": {
                        "text": err.message
                    }
                }]
        };
        err.message = 'cannot ' + method + ' http://127.0.0.1:3002' + url + ' (404)';
        return err;

    }

    pyrusConnectClinical.bypassPatientRecordFilter();

    return {
        get: function(url){
            req = createReq(fixNhsIdentifier(url));
            decorateReq(req);

            var response = httpMocks.createResponse();

            return pyrusConnectClinical.get(req.pyrusUrl, req.organisation['connectionString'])
                .then (function(data) {
                    response.statusCode = 200;
                    response.body = JSON.parse(data);
                    response.setHeader('Content-Length', response.body.length);
                    return response;
                })
                .catch (function(err) {
                    throw generateOperationOutcome(err, 'GET', url);
                });
        },
        post: function(url, data){

            req = createReq(url);
            decorateReq(req);

            var response = httpMocks.createResponse();

            return pyrusConnectClinical.post(req.pyrusUrl, data, req.organisation['connectionString'])
                .then (function(data) {
                    response.statusCode = 201;
                    return response;
                })
                .catch (function(err) {
                    throw generateOperationOutcome(err, 'POST', url);
                });
        },
        put: function(url, data) {
            var response = httpMocks.createResponse();
            response.statusCode = 405;
            return Q(response);
        },
        del: function(data) {
            var response = httpMocks.createResponse();
            response.statusCode = 405;
            return Q(response);
        }
    }
}

module.exports = pyrusConnect;

