text: var MongoDB = require('../../db/mongodb');
  var InfluxDB = require('../../db/influxdb');
  var AppConstants = require('../../constants/AppConstants');
  var Helpers = require('../../common/Helpers');
  var crypto = require('crypto');
  const bcrypt = require('bcryptjs');
  var {ObjectId} = require('mongodb');
  const AccessControl = require('accesscontrol');
  const accessControl = new AccessControl(AppConstants.ACCESS_LIST);
  
  var TenantApi = require('./tenant-api');
  
  function UserApi(){};
  
  UserApi.prototype.handleUserData = function(req, res) {
      var action = req.query.action;
      switch (action) {
          case "registerUserData":
              new UserApi().registerUserData(req, res);
              break;
          case "checkLoginData":
              new UserApi().checkLoginData(req, res);
              break;
          case "removeUserData":
              new UserApi().removeUserData(req, res);
              break;
          case "getUserList":
              new UserApi().getUserList(req, res);
              break;
          case "getUserRolesList":
              new UserApi().getUserRolesList(req, res);
              break;
          case "addInActiveUserData":
              new UserApi().addInActiveUserData(req, res);
              break;
          case "updateUserData":
              new UserApi().updateUserData(req, res);
              break;
          case "addEmailSettingsUserData":
              new UserApi().addEmailSettingsUserData(req, res);
              break;
          case "getUserData":
              new UserApi().getUserData(req, res);
              break;
          case "setEmailPasswordData":
              new UserApi().setEmailPasswordData(req, res);
              break;
          default:
              res.send("no data");
      }
  }
  
  UserApi.prototype.registerUserData = async function(req, res) {
      var userObj = req.body;
  
      if (userObj.password) {
          userObj.password = await hashPassword(userObj.password);
      } else {
          userObj.password = '';
      }
  
      var userInsertObj = {
          email: userObj.email,
          password: userObj.password,
          isActive: true,
          tenants: []
      };
  
      var queryObj = {email: userObj.email};
      var userData = await MongoDB.getAllData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObj);
  
      if (userData.length > 0) {
          res.send({message: AppConstants.USER_EXISTS});
      } else {
          await MongoDB.insertData(AppConstants.DB_NAME, AppConstants.USER_LIST, userInsertObj);
          var tenantObj = await TenantApi.insertTenantData(userInsertObj._id);
  
          var tenantsArray = userInsertObj.tenants;
  
          tenantsArray.push({tenantID: tenantObj._id, role: AppConstants.ADMIN_ROLE});
          var toUpdateTenantArray = {
              tenants: tenantsArray
          };
          MongoDB.updateData(AppConstants.DB_NAME, AppConstants.USER_LIST, {_id: ObjectId(userInsertObj._id)}, toUpdateTenantArray);
  
          // Insert user to tenant id database
          await MongoDB.insertData(String(tenantObj._id), AppConstants.USER_LIST, userInsertObj);
          InfluxDB.createDatabase(String(tenantObj._id));
          res.send({message: AppConstants.RESPONSE_SUCCESS, user: {email: userInsertObj.email}});
      }
  
  }
  
  UserApi.prototype.addInActiveUserData = async function(req, res) {
      var userObj = req.body;
  
      var activationCode = crypto.randomBytes(30).toString('hex');
      var userPasswordBeforEncript = userObj.password;
      userObj.password = await hashPassword(userObj.password);
  
      var userInsertObj = {
          email: userObj.email,
          password: userObj.password,
          isActive: false,
          tenants: [{
              tenantID: userObj.tenantID,
              role: userObj.role,
          }],
          activationCode: activationCode
      };
  
      var queryObj = {email: userObj.email};
      var userData = await MongoDB.getAllData(userObj.tenantID, AppConstants.USER_LIST, queryObj);
  
      if (userData.length > 0) {
          res.send({message: AppConstants.USER_EXISTS});
      } else {
          await MongoDB.insertData(userObj.tenantID, AppConstants.USER_LIST, userInsertObj);
          await MongoDB.insertData(AppConstants.DB_NAME, AppConstants.USER_LIST, userInsertObj);
  
          // Update tenant users array
          var queryToGetTenantObj = {_id: ObjectId(userObj.tenantID)};
          var tenantData = await MongoDB.getAllData(AppConstants.DB_NAME, AppConstants.TENANT_LIST, queryToGetTenantObj);
          var userArray = tenantData[0].users;
          userArray.push({userID: userInsertObj._id});
          var tenantUpdateObj = {
              users: userArray
          };
  
          var queryToUpdateTenant = {_id: ObjectId(userObj.tenantID)};
          MongoDB.updateData(AppConstants.DB_NAME, AppConstants.TENANT_LIST, queryToUpdateTenant, tenantUpdateObj);
  
          var activateURL = userObj.siteURL + '/userAuth?action=activateUser&userID='
                            + userInsertObj._id + '&activationCode=' + activationCode
                            + '&tenantID=' + userObj.tenantID;
  
          // Send warning alert
          var emailBodyToSend = 'Hi ,<br><br>' +
                                  'Your email address is registered in XSUM Site <br>' +
                                  'Please click <a href="' + activateURL +
                                  '">XSUM Site</a> to activate your account <br>' +
                                  'Your password is <b>' + userPasswordBeforEncript + '<b> <br>'
                                  'Regards,<br>xSUM admin';
  
          var queryToGetLoggedUser = {email: userObj.loggedUserEmail};
          var loggedUserData = await MongoDB.getAllData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryToGetLoggedUser);
  
          Helpers.sendEmailFrom(
              userObj.loggedUserEmail,
              loggedUserData[0].emailPassword,
              userObj.email,
              'Activate your account for XSUM',
              emailBodyToSend
          );
  
          res.send({message: AppConstants.RESPONSE_SUCCESS, user: {email: userInsertObj.email}});
      }
  }
  
  UserApi.prototype.updateUserData = async function(req, res) {
      var userObj = req.body;
  
      var queryObjToGetUsers = {email: userObj.email};
      var userData = await MongoDB.getAllData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObjToGetUsers);
  
      for (let tenant of userObj.tenants) {
  
          if (tenant.tenantID == userObj.tenantID) {
              tenant.role = userObj.role;
              break;
          }
  
      }
  
      var userUpdateObj = {
          email: userObj.email,
          tenants: userObj.tenants
      };
  
      if (userData.length > 0) {
          var queryObj = {_id: ObjectId(userObj.id)};
          var existingUserData = await MongoDB.getAllData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObj);
  
          if (existingUserData[0].email === userUpdateObj.email) {
              MongoDB.updateData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObj, userUpdateObj);
              MongoDB.updateData(userObj.tenantID, AppConstants.USER_LIST, queryObj, userUpdateObj);
              res.send({message: AppConstants.RESPONSE_SUCCESS, user: {email: userUpdateObj.email}});
          } else {
              res.send({message: AppConstants.USER_EXISTS});
          }
  
      } else {
          var queryObj = {_id: ObjectId(userObj.id)};
          MongoDB.updateData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObj, userUpdateObj);
          MongoDB.updateData(userObj.tenantID, AppConstants.USER_LIST, queryObj, userUpdateObj);
          res.send({message: AppConstants.RESPONSE_SUCCESS, user: {email: userUpdateObj.email}});
      }
  
  }
  
  UserApi.prototype.addEmailSettingsUserData = async function(req, res) {
      var userObj = req.body;
      var queryObj = {_id: ObjectId(userObj.id)};
      var userUpdateObj = {
          settingEmail: userObj.settingEmail,
          settingEmailPassword: userObj.settingPassword
      }
      MongoDB.updateData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObj, userUpdateObj);
      res.send({message: AppConstants.RESPONSE_SUCCESS, user: {email: userUpdateObj.email}});
  }
  
  UserApi.prototype.setEmailPasswordData = async function(req, res) {
      var userObj = req.body;
      var queryObj = {_id: ObjectId(userObj.id)};
      var userUpdateObj = {
          emailPassword: userObj.emailPassword
      }
      MongoDB.updateData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObj, userUpdateObj);
      res.send({message: AppConstants.RESPONSE_SUCCESS});
  }
  
  UserApi.prototype.getUserData = async function(req, res) {
      var userObj = req.body;
      var queryObjToGetUsers = {email: userObj.email};
      var userData = await MongoDB.getAllData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObjToGetUsers);
  
      if (userData[0].emailPassword && (userData[0].emailPassword !== '')) {
          userData[0].isEmailPasswordSet = true;
      } else {
          userData[0].isEmailPasswordSet = false;
      }
  
      delete userData[0].password;
      delete userData[0].emailPassword;
      delete userData[0].activationCode;
      userData[0].permissions = {
          canCreate: accessControl.can(userData[0].tenants[0].role).createAny(AppConstants.ANY_RESOURCE).granted,
          canRead: accessControl.can(userData[0].tenants[0].role).readAny(AppConstants.ANY_RESOURCE).granted,
          canUpdate: accessControl.can(userData[0].tenants[0].role).updateAny(AppConstants.ANY_RESOURCE).granted,
          canDelete: accessControl.can(userData[0].tenants[0].role).deleteAny(AppConstants.ANY_RESOURCE).granted
      };
  
      res.send(
          {
              message: AppConstants.RESPONSE_SUCCESS,
              user: userData[0]
          }
      );
  }
  
  UserApi.prototype.checkLoginData = async function(req, res) {
      var userObj = req.body;
      var queryObj = {email: userObj.email};
  
      var userData = await MongoDB.getAllData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObj);
  
      if (userData.length > 0) {
          var storedPassword = userData[0].password;
  
          if (userData[0].isActive) {
              if (bcrypt.compareSync(userObj.password, storedPassword)) {
                  res.send({message: AppConstants.RESPONSE_SUCCESS, user: {email: userData[0].email}});
              } else {
                  res.send({message: AppConstants.EMAIL_AND_PASSWORD_NOT_MATCH});
              }
          } else {
              res.send({message: AppConstants.USER_INACTIVE});
          }
  
  
      } else {
          res.send({message: AppConstants.EMAIL_NOT_EXISTS});
      }
  }
  
  UserApi.prototype.removeUserData = async function(req, res) {
      var userObj = req.body;
      var queryToRemoveUser = {
          _id: ObjectId(userObj.userID)
      };
  
      // Get relevant tenant
      var queryToGetTenantObj = {_id: ObjectId(userObj.tenantID)};
      var tenantData = await MongoDB.getAllData(AppConstants.DB_NAME, AppConstants.TENANT_LIST, queryToGetTenantObj);
      var userArray = tenantData[0].users;
      var arrayAfterRemove = [];
  
      // Remove user from tenant
      for (let user of userArray) {
  
          if (user.userID != userObj.userID) {
              arrayAfterRemove.push(user);
          }
  
      }
  
      // Update tenant with remaining user
      var queryTenantObj = {_id: ObjectId(userObj.tenantID)};
      var tenantUpdateObj = {
          users: arrayAfterRemove
      };
  
      MongoDB.updateData(AppConstants.DB_NAME, AppConstants.TENANT_LIST, queryTenantObj, tenantUpdateObj);
      MongoDB.deleteOneData(userObj.tenantID, AppConstants.USER_LIST, queryToRemoveUser);
      MongoDB.deleteOneData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryToRemoveUser);
      res.send(queryToRemoveUser);
  }
  
  UserApi.prototype.getUserList = async function(req, res) {
      var userObj = req.body;
      var queryObj = {};
      var userList = await MongoDB.getAllData(userObj.tenantID, AppConstants.USER_LIST, queryObj);
  
      var userData = [];
  
      for (let user of userList) {
          delete user.password;
          delete user.emailPassword;
          delete user.activationCode;
          userData.push(user);
      }
  
      res.send({userData: userData});
  }
  
  UserApi.prototype.getUserRolesList = function(req, res) {
      var userRoles = [
          {
              type: AppConstants.ADMIN_ROLE
          },
          {
              type: AppConstants.CREATE_ROLE
          },
          {
              type: AppConstants.VIEW_ROLE
          }
      ];
  
      res.send({userRoles: userRoles});
  }
  
  function hashPassword(password) {
      return new Promise((resolve) => {
          bcrypt.hash(password, 10, (err, hash) => {
              resolve(hash);
          });
      });
  }
  
  UserApi.prototype.handleUserGetData = function(req, res) {
      var action = req.query.action;
      switch (action) {
          case "activateUser":
              new UserApi().activateUser(req, res);
              break;
          default:
              res.send("no data");
      }
  }
  
  UserApi.prototype.activateUser = async function(req, res) {
      var paramObj = req.query;
  
      var checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
  
      if (checkForHexRegExp.test(paramObj.userID)) {
          var queryObj = {_id: ObjectId(paramObj.userID)};
          var userDataToActivate = await MongoDB.getAllData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObj);
  
          if (userDataToActivate.length > 0) {
  
              if (userDataToActivate[0].activationCode === paramObj.activationCode) {
  
                  // Activate user
                  var userUpdateObj = {
                      isActive: true,
                      activationCode: ''
                  };
                  var queryObj = {_id: ObjectId(paramObj.userID)};
                  MongoDB.updateData(AppConstants.DB_NAME, AppConstants.USER_LIST, queryObj, userUpdateObj);
                  MongoDB.updateData(paramObj.tenantID, AppConstants.USER_LIST, queryObj, userUpdateObj);
                  res.send("User is activated successful");
              } else {
  
                  if (userDataToActivate[0].activationCode === '' && userDataToActivate[0].isActive) {
                      res.send("User is already activated");
                  } else {
                      res.send("Can't activate user for given activation code");
                  }
  
              }
  
          } else {
             res.send("Can't find user for given user id");
          }
      } else {
          res.send("User id is invalid");
      }
  
  }
  
  module.exports = new UserApi();
  