const { templateName } = require('../backends/template_maps');
const cors = require('../middleware/cors');
const userMiddleware = require('../middleware/user');

/**
 * @param {AuthApi} authApi
 * @param {PgConnection} pgConnection
 * @param {TemplateMaps} templateMaps
 * @constructor
 */
function NamedMapsAdminController(authApi, templateMaps) {
    this.authApi = authApi;
    this.templateMaps = templateMaps;
}

module.exports = NamedMapsAdminController;

NamedMapsAdminController.prototype.register = function (app) {
    app.post(
        app.base_url_templated + '/',
        cors(),
        userMiddleware,
        this.checkContentType('POST', 'POST TEMPLATE'),
        this.authorizedByAPIKey('create', 'POST TEMPLATE'),
        this.create()
    );

    app.put(
        app.base_url_templated + '/:template_id',
        cors(),
        userMiddleware,
        this.checkContentType('PUT', 'PUT TEMPLATE'),
        this.authorizedByAPIKey('update', 'PUT TEMPLATE'),
        this.update()
    );

    app.get(
        app.base_url_templated + '/:template_id',
        cors(),
        userMiddleware,
        this.authorizedByAPIKey('get', 'GET TEMPLATE'),
        this.retrieve()
    );

    app.delete(
        app.base_url_templated + '/:template_id',
        cors(),
        userMiddleware,
        this.authorizedByAPIKey('delete', 'DELETE TEMPLATE'),
        this.destroy()
    );

    app.get(
        app.base_url_templated + '/',
        cors(),
        userMiddleware,
        this.authorizedByAPIKey('list', 'GET TEMPLATE LIST'),
        this.list()
    );

    app.options(
        app.base_url_templated + '/:template_id',
        cors('Content-Type')
    );
};

NamedMapsAdminController.prototype.authorizedByAPIKey = function (action, label) {
    return function authorizedByAPIKeyMiddleware (req, res, next) {
        const { user } = res.locals;

        this.authApi.authorizedByAPIKey(user, req, (err, authenticated) => {
            if (err) {
                return next(err);
            }

            if (!authenticated) {
                const error = new Error(`Only authenticated user can ${action} templated maps`);
                error.http_status = 403;
                error.label = label;
                return next(error);
            }

            next();
        });
    }.bind(this);
};

NamedMapsAdminController.prototype.checkContentType = function (action, label) {
    return function checkContentTypeMiddleware (req, res, next) {
        if (!req.is('application/json')) {
            const error = new Error(`template ${action} data must be of type application/json`);
            error.label = label;
            return next(error);
        }
        next();
    };
};

NamedMapsAdminController.prototype.create = function () {
    return function createTemplateMiddleware (req, res, next) {
        const cdbuser = res.locals.user;
        const cfg = req.body;

        this.templateMaps.addTemplate(cdbuser, cfg, (err, tpl_id) => {
            if (err) {
                return next(err);
            }

            res.status(200);

            const method = req.query.callback ? 'jsonp' : 'json';
            res[method]({ template_id: tpl_id });
        });
    }.bind(this);
};

NamedMapsAdminController.prototype.update = function () {
    return function updateTemplateMiddleware (req, res, next) {
        const cdbuser = res.locals.user;
        const template = req.body;
        const tpl_id = templateName(req.params.template_id);

        this.templateMaps.updTemplate(cdbuser, tpl_id, template, (err) => {
            if (err) {
                return next(err);
            }

            res.status(200);

            const method = req.query.callback ? 'jsonp' : 'json';
            res[method]({ template_id: tpl_id });
        });
    }.bind(this);
};

NamedMapsAdminController.prototype.retrieve =  function () {
    return function updateTemplateMiddleware (req, res, next) {
        req.profiler.start('windshaft-cartodb.get_template');

        const cdbuser = res.locals.user;
        const tpl_id = templateName(req.params.template_id);

        this.templateMaps.getTemplate(cdbuser, tpl_id, (err, tpl_val) => {
            if (err) {
                return next(err);
            }

            if (!tpl_val) {
                const error = new Error(`Cannot find template '${tpl_id}' of user '${cdbuser}'`);
                error.http_status = 404;
                return next(error);
            }
            // auth_id was added by ourselves,
            // so we remove it before returning to the user
            delete tpl_val.auth_id;

            res.status(200);

            const method = req.query.callback ? 'jsonp' : 'json';
            res[method]({ template: tpl_val });
        });
    }.bind(this);
};

NamedMapsAdminController.prototype.destroy = function () {
    return function destroyTemplateMiddleware (req, res, next) {
        req.profiler.start('windshaft-cartodb.delete_template');

        const cdbuser = res.locals.user;
        const tpl_id = templateName(req.params.template_id);

        this.templateMaps.delTemplate(cdbuser, tpl_id, (err/*, tpl_val*/) => {
            if (err) {
                return next(err);
            }

            res.status(204);

            const method = req.query.callback ? 'jsonp' : 'json';
            res[method]('');
        });
    }.bind(this);
};

NamedMapsAdminController.prototype.list = function () {
    return function listTemplatesMiddleware (req, res, next) {
        req.profiler.start('windshaft-cartodb.get_template_list');

        const cdbuser = res.locals.user;

        this.templateMaps.listTemplates(cdbuser, (err, tpl_ids) => {
            if (err) {
                return next(err);
            }

            res.status(200);

            const method = req.query.callback ? 'jsonp' : 'json';
            res[method]({ template_ids: tpl_ids });
        });
    }.bind(this);
};

@@ -526,25 +526,22 @@
     
-app.post(%0A       
+const prefix =
  app
@@ -551,38 +551,69 @@
 se_url_templated
- + '/'
+;%0A%0A    app.post(%0A        %60$%7Bprefix%7D/%60
 ,%0A        cors()
@@ -809,34 +809,18 @@
     
-app.base_url_templated + '
+%60$%7Bprefix%7D
 /:te
@@ -820,33 +820,33 @@
 ix%7D/:template_id
-'
+%60
 ,%0A        cors()
@@ -1039,34 +1039,18 @@
     
-app.base_url_templated + '
+%60$%7Bprefix%7D
 /:te
@@ -1050,33 +1050,33 @@
 ix%7D/:template_id
-'
+%60
 ,%0A        cors()
@@ -1217,34 +1217,18 @@
     
-app.base_url_templated + '
+%60$%7Bprefix%7D
 /:te
@@ -1228,33 +1228,33 @@
 ix%7D/:template_id
-'
+%60
 ,%0A        cors()
@@ -1397,36 +1397,20 @@
     
-app.base_url_templated + '/'
+%60$%7Bprefix%7D/%60
 ,%0A  
@@ -1566,34 +1566,18 @@
     
-app.base_url_templated + '
+%60$%7Bprefix%7D
 /:te
@@ -1585,17 +1585,17 @@
 plate_id
-'
+%60
 ,%0A      

Use template string