/*
 * routes.js - module to provide routing
 */

/*jslint         node    : true, continue : true,
  devel  : true, indent  : 2,    maxerr   : 50,
  newcap : true, nomen   : true, plusplus : true,
  regexp : true, sloppy  : true, vars     : false,
  white  : true
*/
/*global */

// ------------ BEGIN MODULE SCOPE VARIABLES --------------
'use strict';
var
    configRoutes,
    dat = require('./dat'),
    jwt = require('jsonwebtoken'), // used to create, sign, and verify tokens
    response = require('./response-codes.js'),
    kg = require('./kg.js'),
    keyRequests = require('./key-requests.js'),
    makeMongoId = dat.makeMongoId;
// ------------- END MODULE SCOPE VARIABLES ---------------

// ---------------- BEGIN PUBLIC METHODS ------------------

//STATIC FILES FOR APP
configRoutes = function (app, server) {




    //**********************************
    //GET - STATIC SITE
    app.get('/', function (req, res) {
        res.redirect('/app.html');
    });


    //**********************************
    //MIDDLEWARE - SET CORS OPTIONS PREFLIGHT ROUTE
    app.route('*')
        .options(function (req, res, next) {
            res.status(200).end();
        });



    //**********************************
    //GET - INITIALIZE RAW DATABASE
    app.get('/INITIALIZE_ME', function (req, res) {
        dat.initialize(function (err, result) {
            if (err) {
                res.send(response.errorResponse(err));
            } else {
                res.json(result);
            }
        })
    });



    /*
                _____ _____   _____   ____  _    _ _______ ______  _____ 
         /\   |  __ \_   _| |  __ \ / __ \| |  | |__   __|  ____|/ ____|
        /  \  | |__) || |   | |__) | |  | | |  | |  | |  | |__  | (___  
       / /\ \ |  ___/ | |   |  _  /| |  | | |  | |  | |  |  __|  \___ \ 
      / ____ \| |    _| |_  | | \ \| |__| | |__| |  | |  | |____ ____) |
     /_/    \_\_|   |_____| |_|  \_\\____/ \____/   |_|  |______|_____/ 
                                                                        
      */



    //*************** NOT AUTHENTICATED ROUTES **********************

    //POST - GET AN AUTHENTICATION TOKEN   
    // router.route('/authenticate')
    app.post('/authenticate', function (req, res) {
        dat.authenticate(req.body, function (err, result) {
            if (err) {
                res.send(response.errorResponse(err));
            } else {
                res.json(result);
            }
        })
    });


    //****************  AUTHENTICATED ROUTES ************************

    //*************************
    //AUTHENTICATION MIDDLEWARE  
    app.all('/api/*', function (req, res, next) {

        // check header or url parameters or post parameters for token
        var token = req.body.token || req.query.token || req.headers['x-access-token'];
        //console.log("server.js router req:");
        //console.log(req);
        // decode token
        if (token) {

            // verifies secret and checks exp
            jwt.verify(token, 'Nothing8utTheRain', function (err, decoded) {
                if (err) {
                    return res.status(401).json({
                        success: false,
                        message: 'Failed to authenticate token.'
                    });
                } else {
                    // if everything is good, save to req for use in other routes
                    req.apitoken = decoded;
                    next();
                }
            });

        } else {

            // if there is no token
            // return an error
            return res.status(401).send({
                success: false,
                message: 'No token provided.'
            });

        }
    });
    //================================



    //**********************************
    //MIDDLEWARE - SET DEFAULT CONTENT TYPE
    app.all('/api/:obj_type/*?', function (req, res, next) {
        res.contentType('json');
        next();
    });


    //**********************************
    //GET - LIST
    app.get('/api/:obj_type/list', function (req, res) {
        var srt = {};
        if (req.query.sortBy) {
            srt = {
                "sort": [req.query.sortBy, 'asc']
            }
        }
        dat.read(
            req.params.obj_type, {}, srt,
            function (map_list) {
                res.send(map_list);
            }
        );
    });


    //**********************************
    //GET - AUTOCOMPLETE
    app.get('/api/autocomplete', function (req, res) {
        dat.autocomplete(
            req.query,
            function (map_list) {
                res.send(map_list);
            }
        );
    });



    //**********************************
    //GET - SEARCH
    app.get('/api/search', function (req, res) {
        dat.search(
            req.query.query,
            function (map_list) {
                res.send(map_list);
            }
        );
    });



    //**********************************
    //GET - RELATIVE LIST
    app.get('/api/:obj_type/relativelist', function (req, res) {

        var queryOptions = {};


        if (req.query.sortBy) {

            var sortDir = 'asc';
            if (req.query.sortDir) {
                if (req.query.sortDir == 'd') {
                    sortDir = 'desc';
                }
            }

            //example {'skip':1, 'limit':1, 'sort':'a'}
            queryOptions = {
                "sort": [
                    [req.query.sortBy, sortDir]
                ]
            }
        }




        var q = {};
        //     params = '?masterField=' + masterFieldName + '&masterId=' + masterId;
        if (req.query.masterField && req.query.masterId) {
            q[req.query.masterField] = req.query.masterId
        } else {
            res.send({
                error_msg: 'routes.js::relativeList->missing parameters for master record',
                error_list: []
            });
        }



        dat.read(
            req.params.obj_type,
            q, //findmap
            queryOptions, //query options
            function (map_list) {
                res.send(map_list);
            }
        );
    });


    //**********************************
    //CREATE 
    app.post('/api/:obj_type/create', function (req, res) {
        dat.construct(
            req.params.obj_type,
            req.body,
            function (result_map) {
                // console.log('routes.js::app.post->result_map object about to be sent is:');
                // console.log(result_map);
                res.send(result_map);
            }
        );
    });


    //**********************************
    //GET - NO ID
    app.get('/api/:obj_type/read', function (req, res) {
        dat.read(
            req.params.obj_type,
            {}, //no find map for this route
            {},
            function (map_list) {
                res.send(map_list[0]);
            }
        );
    });

    //**********************************
    //GET - WITH ID
    app.get('/api/:obj_type/read/:id', function (req, res) {
        dat.read(
            req.params.obj_type, {
                _id: makeMongoId(req.params.id)
            }, {},
            function (map_list) {
                res.send(map_list[0]);
            }
        );
    });


    //******************************************
    //GET - NAME ONLY 
    app.get('/api/:obj_type/readName/:id', function (req, res) {
        dat.read(
            req.params.obj_type, {
                _id: makeMongoId(req.params.id)
            }, {
                "name": 1
            },
            function (map_list) {
                res.send(map_list[0]);
            }
        );
    });


    //**********************************
    //UPSERT - for single non=id records only (like global settings etc)
    app.post('/api/:obj_type/upsert', function (req, res) {
        dat.upsert(
            req.params.obj_type,
            req.body,
            function (result_map) {
                res.send(result_map);
            }
        );
    });


    //**********************************
    //UPDATE
    app.post('/api/:obj_type/update/:id', function (req, res) {
        dat.update(
            req.params.obj_type, {
                _id: makeMongoId(req.params.id)
            },
            req.body,
            function (result_map) {
                res.send(result_map);
            }
        );
    });


    //**********************************
    //DELETE
    app.get('/api/:obj_type/delete/:id', function (req, res) {
        dat.destroy(
            req.params.obj_type, {
                _id: makeMongoId(req.params.id)
            },
            function (result_map) {
                res.send(result_map);
            }
        );
    });


    //**********************************
    //DELETE BY RELATIONSHIP
    //delete many items by query params
    //for deleteing records that have matching field and id in them
    //(i.e. delete all contacts that have customer_id field eq to id provided)
    app.get('/api/:obj_type/deleterelated', function (req, res) {

        var q = {};
        //     params = '?masterField=' + masterFieldName + '&masterId=' + masterId;
        if (req.query.masterField && req.query.masterId) {
            q[req.query.masterField] = req.query.masterId
        } else {
            res.send({
                error_msg: 'routes.js::deleterelated->missing parameters for master record',
                error_list: []
            });
        }



        dat.destroyMany(
            req.params.obj_type, q,
            function (result_map) {
                res.send(result_map);
            }
        );
    });

    app.get('/api/:obj_type/readName/:id', function (req, res) {
        dat.read(
            req.params.obj_type, {
                _id: makeMongoId(req.params.id)
            }, {
                "name": 1
            },
            function (map_list) {
                res.send(map_list[0]);
            }
        );
    });


    /////////////////////////////////////////
    // KEY HANDLING ROUTES
    /////////////////////////////////////////



    //**********************************
    // GENERATE KEY ROUTE    
    app.post('/api/license/generate', function (req, res) {
        kg.generate(req,
            function (result) {
                res.send(result);
            }
        )
    });

    //**********************************
    // GET KEY REQUESTS ROUTE    
    app.get('/api/license/requests', function (req, res) {
        keyRequests.requests(req,
            function (result) {
                res.send(result);
            }
        )
    });

    //**********************************
    // GENERATE KEY FROM REQUEST ROUTE    
    app.get('/api/license/generate_from_request/:uid', function (req, res) {
        keyRequests.generate_from_request(req,
            function (result) {
                res.send(result);
            }
        )
    });

    //**********************************
    // SEND REQUESTED KEY ROUTE    
    app.post('/api/license/email_response', function (req, res) {
        keyRequests.email_response(req,
            function (result) {
                res.send(result);
            }
        )
    });


    //**********************************
    //**********************************
    //end of routes

};

module.exports = {
    configRoutes: configRoutes
};
// ----------------- END PUBLIC METHODS -------------------