text: /**
   *
   * @param authKey
   * 
  **/
  module.exports = function (authKey) {
  
      if (authKey == null || authKey == "") {
          throw new Error("MSG91 Authorization Key not provided.");
      }
  
      this.otp_length = 4; // default: 4, min: 4, max: 9
      this.otp_expiry = 1440; // default 1 Day = 1440 minutes
      this.retry_type = 'voice';
  
      this.sendSMS = function (args, callback) {
  
          callback = modifyCallbackIfNull(callback);
  
          args = isData(args);
  
          var options = {
              method: 'POST',
              hostname: 'api.msg91.com',
              port: null,
              path: '/api/v5/flow/',
              headers: {
                  'Content-Type': 'application/JSON',
                  'authkey': authKey
              }
          };
  
          makeHttpRequest(options, args, function(err, data){
              callback(err, data);
          });
      };    
  
      /**
       * Set the OTP expiry minutes for MSG91 api call
       */
      this.setOtpExpiry = function (otp_expiry) {
          this.otp_expiry = otp_expiry;
          return;
      };
  
      /**
       * Set the OTP length for MSG91 api call
       */
      this.setOtpLength = function (otp_length) {
          this.otp_length = otp_length;
          return;
      };
  
      /**
       * Send Otp to given mobile number
       * @param {string} contactNumber receiver's mobile number along with country code
       * @param {string} templateId
       * @param {string, optional} params // otp, otp_expiry, etc
       * Return promise if no callback is passed and promises available
       */
      this.sendOTP = function (mobileNo, templateId, params, args, callback) {
          if (typeof args === 'function') {
              callback = args;
              args = null;
          }
  
          callback = modifyCallbackIfNull(callback);
  
          mobileNo = validateMobileNos(mobileNo);
  
          templateId = validateTemplate(templateId);
  
          args = isData(args);
  
          if (!params["otp"]) {
              params["otp"] = generateOTP(this.otp_length);
              params["otp_expiry"] = this.otp_expiry;
          } else if (!params["otp_expiry"]) params["otp_expiry"] = this.otp_expiry;        
  
          var urlParameters = Object.entries(params || {}).map(function (e) { e.join('=') }).join('&');
  
          var apiAuth = "template_id=" + templateId + "&mobile=" + mobileNo + "&authkey=" + authKey;
          if (urlParameters) apiAuth += "&" + urlParameters;
  
          var options = {
              method: 'GET',
              hostname: 'api.msg91.com',
              port: null,
              path: '/api/v5/otp?' + apiAuth,
              headers: {
                  'Content-Type': 'application/JSON',
              }
          };
  
          makeHttpRequest(options, args, function(err, data){
              callback(err, data);
          });
      };
  
      this.verifyOTP = function (mobileNos, otp, callback) {
          var params = {
              otp: otp,
              otp_expiry: this.otp_expiry
          };
  
          callback = modifyCallbackIfNull(callback);
  
          mobileNos = validateMobileNos(mobileNos);
  
          var urlParameters = Object.entries(params || {}).map(function (e) { e.join('=') }).join('&');
  
          var apiAuth = "mobile=" + mobileNos + "&authkey=" + authKey;
          if (urlParameters) apiAuth += "&" + urlParameters;
  
          var options = {
              method: 'GET',
              hostname: 'api.msg91.com',
              port: null,
              path: '/api/v5/otp/verify?' + apiAuth,
              headers: {}
          };
  
          makeHttpRequest(options, null, function(err, data){
              callback(err, data);
          });
      };
  
      this.resendOTP = function (mobileNos, retryType, callback) {
          if (typeof retryType === 'function') {
              callback = retryType;
              retryType = this.retry_type;
          }
  
          callback = modifyCallbackIfNull(callback);
  
          mobileNos = validateMobileNos(mobileNos);
  
          var apiAuth = "authkey=" + authKey + "&mobile=" + mobileNos + "&retrytype=" + retryType;
          
          var options = {
              method: 'GET',
              hostname: 'api.msg91.com',
              port: null,
              path: '/api/v5/otp/retry?' + apiAuth,
              headers: {}
          };
  
          makeHttpRequest(options, null, function(err, data){
              callback(err, data);
          });
      };
  
      this.getBalance = function(customRoute, callback) {
  
          if(arguments.length == 1) {
              callback = customRoute;
              customRoute = null;
          }
  
          callback = modifyCallbackIfNull(callback);
  
          var currentRoute = customRoute || 1;
          
          var apiAuth = 'authkey=' + authKey + '&type=' + currentRoute;
          
          var options = {
              method: 'GET',
              port: null,
              hostname: 'api.msg91.com',
              path: '/api/balance.php?' + apiAuth,
              headers: {}
          };
  
          makeHttpRequest(options, null, function(err, data){
              callback(err, data);
          });
      };
  
      return this;
  };
  
  function generateOTP (otpLen) {
            
      // Declare a string variable
      // which stores all string
      var string = '0123456789';
      var OTP = '';
        
      // Find the length of string
      var len = string.length;
      for (var i = 0; i < otpLen; i++ ) {
          OTP += string[Math.floor(Math.random() * len)];
      }
      return OTP;
  }
  
  function validateMobileNos(mobileNos){
  
      if (mobileNos == null || mobileNos == "") {
          throw new Error("MSG91 : Mobile No is not provided.");
      }
  
      if(mobileNos instanceof Array){
          mobileNos = mobileNos.join(",");
      }
  
      return mobileNos
  }
  
  function validateTemplate(template){
  
      if (template == null || template == "") {
          throw new Error("MSG91 : template id is not provided.");
      }
  
      return template;
  }
  
  function modifyCallbackIfNull(callback){
      return callback || function(){};
  }
  
  function isData(payload) {
      if (payload) return (typeof payload === 'object' ? JSON.stringify(payload) : payload);
      return null;
  }
  
  function makeHttpRequest(options, postData, callback) {
      var http = require("https");
      var data = "";
      var req = http.request(options, function (res) {
          res.setEncoding('utf8');
          res.on('data', function (chunk) {
              data += chunk;
          });
          res.on('end', function () {
              try {
                  data = JSON.parse(data);
                  callback(null, data);
              } catch (e) {
                  callback(e);
              }
          });
      });
  
      req.on('error', function (e) {
          callback(e);
      });
  
      if(postData!=null){
          req.write(postData);
      }
  
      req.end();
  
  }
  