/**
 * user.js
 * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Contact:
 * Sungmin Kim <sm.art.kim@samsung.com>
 * Jonghwan Park <iwin100.park@samsung.com>
 * Kitae Kim <kt920.kim@samsung.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 * - S-Core Co., Ltd
**/

var dibs = require('../../../core/dibs');
var expressio = require('express.io');
var session = require('./session');
var async = require('async');

var router = new expressio.Router();
module.exports.router = router;


router.post('/signup', function (req, res) {
    session.createAccount(req, res, function (err, code) {
        if (err) {
            dibs.log.error(JSON.stringify(err));
            res.status(code).send(JSON.stringify(err.message));
        } else {
            res.status(code).send();
        }
    });
});


router.post('/login', function (req, res) {
    session.createSession(req, res, function (err, code) {
        if (err) {
            dibs.log.error(JSON.stringify(err));
            res.status(code).send(JSON.stringify({
                error: 'Can\'t access user data'
            }));
        } else {
            if (code === 200) {
                res.status(code).send({
                    email: req.session.email,
                    admin: req.session.admin,
                    status: req.session.status
                });
            //res.status(code).send(JSON.stringify({email:req.session.email, admin:req.session.admin, status:req.session.status}));
            } else if (code === 404) {
                res.status(code).send(JSON.stringify({
                    error: 'Can\'t find your email'
                }));
            } else if (code === 401) {
                res.status(code).send(JSON.stringify({
                    error: 'Password is not correct'
                }));
            }
        }
    });
});


router.delete('/logout', function (req, res) {
    session.deleteSession(req, res, function (err, result) {
        if (err) {
            dibs.log.error(JSON.stringify(err));
        }
        res.status(200).send('Session is deleted.');
    });
});


router.get('/users', session.checkSession, function (req, res) {
    dibs.rpc.datamgr.searchUsers({}, function (err, users) {
        if (err) {
            dibs.log.error(JSON.stringify(err));
            res.status(503).send(JSON.stringify(err.message));
        } else {
            res.send(JSON.stringify(users));
        }
    });
});


router.get('/users/:email', session.checkSession, function (req, res) {
    var email = req.param('email');
    dibs.rpc.datamgr.searchUsers({
        email: email
    }, function (err, users) {
        if (err) {
            dibs.log.error(JSON.stringify(err));
            res.status(503).send(JSON.stringify(err.message));
        } else {
            res.send(JSON.stringify(users[0]));
        }
    });
});


router.get('/userImage/:email', session.checkSession, function (req, res) {
    var email = req.param('email');
    dibs.rpc.datamgr.searchUsers({
        email: email
    }, function (err, users) {
        if (err) {
            dibs.log.error(JSON.stringify(err));
            res.status(503).send(JSON.stringify(err.message));
        } else if (users.image_id) {
            res.status(404).send(JSON.stringify({
                error: 'Can\'t find image'
            }));
        } else {
            dibs.rpc.datamgr.searchImage({
                id: users[0].image_id
            }, function (err, image) {
                if (err) {
                    dibs.log.error(JSON.stringify(err));
                    res.status(503).send(JSON.stringify(err.message));
                } else {
                    res.send({
                        name: image.name,
                        size: image.size,
                        contents: image.contents
                    });
                }
            });
        }
    });
});

router.put('/users/:userId', session.checkSession, function (req, res) {
    var userId = req.param('userId');
	var email = req.body.email;
	var name  = req.body.name;
	var status = req.body.status;
	var groups = req.body.groups;
	var options = req.body.options;
	var oldPassword = req.body.oldPassword;
	var password = req.body.password;
	var resetPassword = req.body.resetPassword;

    dibs.rpc.datamgr.searchUsers( {id:userId}, function(err, results) {
        if (err) {
            dibs.log.error(JSON.stringify(err));
            res.status(503).send(JSON.stringify(err.message));
        } else {
            if ( resetPassword === null ) {
                dibs.rpc.datamgr.resetUserPassword( userId, function(err, user ) {
                    if (err) {
                        dibs.log.error(JSON.stringify(err));
                        res.status(503).send(JSON.stringify(err.message));
                    } else {
                        res.send();
                    }
                });
            } else {
                var user = results[0];
                if (name) { user.name = name; }
                if (email) { user.email = email; }
                if (status) { user.status = status; }
                if (groups) { user.groups = groups; }
                if (options) { user.options = options; }

                async.waterfall([
                    function (cb) {
                        if (oldPassword && password) {
                            session.isValidPassword(oldPassword, user.password_salt, user.password_hash, function (truth) {
                                if (truth) {
                                    cb(null);
                                } else {
                                    cb(new Error('Your old password was entered incorrectly'));
                                }
                            });
                        } else {
                            cb(null);
                        }
                    },
                    function (cb) {
                        if (oldPassword && password) {
                            session.genPasswordHash(password, cb);
                        } else {
                            cb(null, null, null);
                        }
                    },
                    function (hash, salt, cb) {
                        if (hash && salt) {
                            user.password_hash = hash;
                            user.password_salt = salt;
                        }
                        dibs.rpc.datamgr.updateUser(user, function (err) {
                            cb(err);
                        });
                    }],
                    function (err) {
                    if (err) {
                        dibs.log.error(JSON.stringify(err));
                        res.status(503).send(JSON.stringify(err.message));
                    } else {
                        res.send();
                    }
                });
            }
        }
    });
});


router.delete('/users/:userId', session.checkSession, function (req, res) {
    var userId = req.param('userId');

    async.waterfall([
        function (cb) {
            dibs.rpc.datamgr.removeUser(userId, cb);
        }], function (err) {
        if (err) {
            dibs.log.error(err);
            res.status(503).send(JSON.stringify(err.message));
        } else {
            res.send();
        }
    });
});


router.post('/userImage/:userId', function (req, res) {
    var userId = req.param('userId');
    var downloadedPath = req.files.uploadedfiles[0].path;
    var fileName = req.files.uploadedfiles[0].name;
    var datamgr = dibs.getServersByType('datamgr')[0];
    var user = null;
    async.waterfall([
        function (cb) {
            datamgr.searchUsers({
                id: userId
            }, function (err, users) {
                cb(err, users);
            });
        },
        // insert db server
        function (users, cb) {
            user = users[0];
            datamgr.addImageFromFile(downloadedPath, fileName, function (err, insertId) {
                cb(err, insertId);
            });
        },
        // remove temporarily-downloaded file
        function (insertId, cb) {
            user.image_id = insertId;
            datamgr.updateUser(user, function (err) {
                cb(err);
            });
        }
    ], function (err) {
        //fs.unlinkSync(downloadedPath);
        if (err) {
            res.status(503).send(JSON.stringify(err.message));
        } else {
            res.status(200).send(JSON.stringify({}));
        }
    });
});


router.get('/groups', session.checkSession, function (req, res) {
    dibs.rpc.datamgr.searchUserGroups({}, function (err, groups) {
        if (err) {
            dibs.log.error(JSON.stringify(err));
            res.status(503).send(JSON.stringify(err.message));
        } else {
            res.send(JSON.stringify(groups));
        }
    });
});


router.post('/groups', session.checkSession, function (req, res) {
    var name = req.body.name;
    var type = req.body.status;
    var description = req.body.description;
    var options = req.body.options;

    dibs.rpc.datamgr.addUserGroup(name, type, description, options, function (err, group) {
        if (err) {
            dibs.log.error(JSON.stringify(err));
            res.status(503).send(JSON.stringify(err.message));
        } else {
            res.send();
        }
    });
});


router.put('/groups/:groupId', session.checkSession, function (req, res) {
    var id = req.param('groupId');
    var name = req.body.name;
    var type = req.body.type;
    var description = req.body.description;
    var status = req.body.status;
    var projects = req.body.projects;
    var options = req.body.options;

    dibs.rpc.datamgr.searchUserGroups({
        id: id
    }, function (err, results) {
        if (err) {
            dibs.log.error(JSON.stringify(err));
            res.status(503).send(JSON.stringify(err.message));
        } else {
            var group = results[0];
            if (name !== null) {
                group.name = name;
            }
            if (type !== null) {
                group.type = type;
            }
            if (description !== null) {
                group.description = description;
            }
            if (status !== null) {
                group.status = status;
            }
            if (projects !== null) {
                group.projects = projects;
            }
            if (options !== null) {
                group.options = options;
            }

            dibs.rpc.datamgr.updateUserGroup(group, function (err, g) {
                if (err) {
                    dibs.log.error(JSON.stringify(err));
                    res.status(503).send(JSON.stringify(err.message));
                } else {
                    res.send();
                }
            });
        }
    });
});


router.delete('/groups/:groupId', session.checkSession, function (req, res) {
    var groupId = req.param('groupId');

    async.waterfall([
        function (cb) {
            dibs.rpc.datamgr.removeUserGroup(groupId, cb);
        }], function (err) {
        if (err) {
            dibs.log.error(err);
            res.status(503).send(JSON.stringify(err.message));
        } else {
            res.send();
        }
    });
});
