@RequestMapping(value = "/pay_merchant", method = RequestMethod.POST)
  public String paymerchantPageAction(
      @ModelAttribute("paymerchantOp") TempTransactions transactionObj,
      Model model,
      HttpSession session)
      throws IOException {
    logger.info("Inside pay merchant op POST");

    /** To display user profile */
    UserInfo UI = new UserInfo();
    DatabaseConnectors dbcon = new DatabaseConnectors();
    UI = dbcon.getUserInfoByUniqId((String) session.getAttribute("uniqueid"));
    String uniqueID = (String) session.getAttribute("uniqueid");
    ExternalUser extUser = databaseConnector.getExternalUserByUniqId(uniqueID);
    String utype = null;
    String str1 = (String) session.getAttribute("uniqueid");
    System.out.println(str1);
    String str2 = str1.substring(0, 2);

    if (str2.equals("ei")) {
      utype = "Single User";
    } else if (str2.equals("em")) {
      utype = "Merchant";
    } else if (str2.equals("ir")) {
      utype = "Internal User";
    } else if (str2.equals("im")) {
      utype = "Manager";
    } else if (str2.equals("admin")) {
      utype = "Administrator";
    }

    model.addAttribute("firstName", UI.getFirstName());
    model.addAttribute("lastName", UI.getLastName());
    model.addAttribute("Username", UI.getUsername());
    model.addAttribute("email", UI.getEmailId());
    model.addAttribute("accountno", extUser.getAccountno());
    model.addAttribute("streetAddress", UI.getAddress());
    model.addAttribute("city", UI.getCity());
    model.addAttribute("state", UI.getState());
    model.addAttribute("country", UI.getCountry());
    model.addAttribute("zip", UI.getZipcode());
    model.addAttribute("contactNo", UI.getContactNo());
    model.addAttribute("userType", utype);

    logger.info("Current user" + uniqueID);

    MultipartFile fileGot = transactionObj.getMpFile();
    String file_name = fileGot.getOriginalFilename();

    ServletContext context = session.getServletContext();
    String realContextPath = context.getRealPath("/");

    //	            String certpath = realContextPath+"/certificates/"+fileGot.getOriginalFilename();
    String certpath = realContextPath + "/certificates/" + uniqueID + "_cert.pem";

    String temp__2_2 = realContextPath + "/certificates";
    File temp_1_2 = new File(temp__2_2);
    if (!temp_1_2.exists()) temp_1_2.mkdirs();

    File convFile = new File(certpath);
    convFile.createNewFile();
    FileOutputStream fos = new FileOutputStream(convFile);
    fos.write(fileGot.getBytes());
    fos.close();

    if (pkiGringott.verifyCertificate(uniqueID, session) == false) {
      logger.info(certpath);
      logger.info("uniqId is:" + uniqueID);
      logger.info("Certificate verification is failed");
      model.addAttribute("message", "Certificate verification failed");

      Transactions transObj_1 = new Transactions();
      //					logger.info("Ext User"+extUser);
      // transObj.setBalance(extUser.getBalance());

      TempTransactions temp_1 = new TempTransactions();
      temp_1.setBalance(transactionObj.getBalance());

      model.addAttribute("debitOp", transObj_1);
      model.addAttribute("creditOp", transObj_1);
      model.addAttribute("checkAccBal", transObj_1.getBalance());
      model.addAttribute("savingAccBal", "500");
      model.addAttribute("transferOp", temp_1);
      model.addAttribute("paymerchantOp", temp_1);
      model.addAttribute("transactionOp", temp_1);
      model.addAttribute("UpdateProfile", new UserInfo());
      List<Transactions> obj_1 = displaytransaction(session);
      if (obj_1 == null) {
        model.addAttribute("transactionOp", null);
      } else {
        model.addAttribute("transactionOp", obj_1);
      }

      return "extUserHomePage";
    } else {
      logger.info("uniqId is:" + uniqueID);
      logger.info("Certificate verified");
    }

    MultipartFile pkf = transactionObj.getPkFile();

    String pkf_name = pkf.getOriginalFilename();
    logger.info(pkf_name);

    //				String pkpath = realContextPath+"/privatekeys/"+pkf.getOriginalFilename();
    String pkpath = realContextPath + "/privatekeys/" + uniqueID + "_private.key";

    String temp_1 = realContextPath + "/privatekeys";
    File temp_1_1 = new File(temp_1);
    if (!temp_1_1.exists()) temp_1_1.mkdirs();

    File convFile_1 = new File(pkpath);
    convFile_1.createNewFile();
    FileOutputStream fos_1 = new FileOutputStream(convFile_1);
    fos_1.write(pkf.getBytes());
    fos_1.close();

    if (pkiGringott.verifyPrivateKey(uniqueID, session) == false) {
      logger.info(pkpath);
      logger.info("uniqId is:" + uniqueID);
      logger.info("private key verification is failed");
      model.addAttribute("message", "private key verification failed");

      Transactions transObj_2 = new Transactions();
      //					logger.info("Ext User"+extUser);
      // transObj.setBalance(extUser.getBalance());

      TempTransactions temp_2 = new TempTransactions();
      temp_2.setBalance(transactionObj.getBalance());

      model.addAttribute("debitOp", transObj_2);
      model.addAttribute("creditOp", transObj_2);
      model.addAttribute("checkAccBal", transObj_2.getBalance());
      // model.addAttribute("savingAccBal", "500" );
      model.addAttribute("transferOp", temp_2);
      model.addAttribute("paymerchantOp", temp_2);
      model.addAttribute("transactionOp", temp_2);
      model.addAttribute("UpdateProfile", new UserInfo());
      List<Transactions> obj_2 = displaytransaction(session);
      if (obj_2 == null) {
        model.addAttribute("transactionOp", null);
      } else {
        model.addAttribute("transactionOp", obj_2);
      }

      return "extUserHomePage";
    } else {
      logger.info("uniqId is:" + uniqueID);
      logger.info("Private key verified");
    }

    transactionObj.setBalance(extUser.getBalance());
    logger.info("Current Balance" + transactionObj.getBalance());
    float amount = transactionObj.getTransactionAmount();
    float currentBalance = transactionObj.getBalance();
    logger.info("balance :", currentBalance);
    logger.info("account number ", transactionObj.getAccountno());
    // credit amount from current account balance

    ExternalUser merch = databaseConnector.getExternalUserByAccNum(transactionObj.getAccountno());
    if (merch == null) {
      model.addAttribute("message", "Account number is invalid");
      Transactions transObj_2 = new Transactions();
      //					logger.info("Ext User"+extUser);
      // transObj.setBalance(extUser.getBalance());

      TempTransactions temp_2 = new TempTransactions();
      temp_2.setBalance(transactionObj.getBalance());

      model.addAttribute("debitOp", transObj_2);
      model.addAttribute("creditOp", transObj_2);
      model.addAttribute("checkAccBal", transObj_2.getBalance());
      // model.addAttribute("savingAccBal", "500" );
      model.addAttribute("transferOp", temp_2);
      model.addAttribute("paymerchantOp", temp_2);
      model.addAttribute("transactionOp", temp_2);
      model.addAttribute("UpdateProfile", new UserInfo());
      List<Transactions> obj_2 = displaytransaction(session);
      if (obj_2 == null) {
        model.addAttribute("transactionOp", null);
      } else {
        model.addAttribute("transactionOp", obj_2);
      }

      return "extUserHomePage";
    }

    transactionObj.setUniqId(uniqueID);
    transactionObj.setDescription("transferred amount: " + amount);
    transactionObj.setTransactionType("tranfer");
    transactionObj.setBalance(currentBalance - amount);

    // extUser.setBalance(currentBalance-amount);
    // databaseConnector.updateExternalUser(extUser);
    databaseConnector.saveTempTransaction(transactionObj);

    Transactions temp = new Transactions();
    temp.setBalance(transactionObj.getBalance());
    model.addAttribute("debitOp", temp);
    model.addAttribute("creditOp", temp);
    model.addAttribute("checkAccBal", temp.getBalance());
    model.addAttribute("transferOp", transactionObj);
    model.addAttribute("paymerchantOp", transactionObj);
    model.addAttribute("UpdateProfile", new UserInfo());
    List<Transactions> obj = displaytransaction(session);
    if (obj == null) {
      model.addAttribute("transactionOp", null);
    } else {
      model.addAttribute("transactionOp", obj);
    }

    logger.info("Leaving transfer money POST");
    return "extUserHomePage";
  }
  @RequestMapping(value = "/download", method = RequestMethod.GET)
  public void downloadStatement(HttpSession session, HttpServletResponse response, Model model)
      throws IOException {
    String uniqId = session.getAttribute("uniqueid").toString();
    StatementGenerator.statementbyuniqid(uniqId, session);
    ExternalUser extUser = databaseConnector.getExternalUserByUniqId(uniqId);
    TempTransactions transactionObj = new TempTransactions();
    transactionObj.setBalance(extUser.getBalance());
    logger.info("Current Balance" + transactionObj.getBalance());
    float amount = transactionObj.getTransactionAmount();
    float currentBalance = transactionObj.getBalance();
    logger.info("balance :", currentBalance);
    logger.info("account number ", transactionObj.getAccountno());
    // credit amount from current account balance

    transactionObj.setUniqId(uniqId);
    transactionObj.setDescription("transferred amount: " + amount);
    transactionObj.setTransactionType("tranfer");
    transactionObj.setBalance(currentBalance - amount);

    extUser.setBalance(currentBalance - amount);

    Transactions temp = new Transactions();
    temp.setBalance(transactionObj.getBalance());
    model.addAttribute("debitOp", temp);
    model.addAttribute("creditOp", temp);
    model.addAttribute("checkAccBal", temp.getBalance());
    model.addAttribute("transferOp", transactionObj);
    model.addAttribute("paymerchantOp", transactionObj);
    List<Transactions> obj = displaytransaction(session);
    model.addAttribute("transactionOp", obj);
    // get absolute path of the application
    ServletContext context = session.getServletContext();

    String realContextPath = context.getRealPath("/");
    String fullpath = realContextPath + "/statement/" + uniqId + "_statement.pdf";
    //  System.out.println("aPath = " +realContextPath);
    // String filePath="Statement.pdf";
    // construct the complete absolute path of the file
    //  String fullPath = realContextPath+filePath;
    System.out.println(fullpath);

    File downloadFile = new File(fullpath);
    FileInputStream inputStream = new FileInputStream(downloadFile);

    // get MIME type of the file
    String mimeType = context.getMimeType(fullpath);
    if (mimeType == null) {
      // set to binary type if MIME mapping not found
      mimeType = "application/pdf";
    }
    System.out.println("MIME type: " + mimeType);

    // set content attributes for the response
    response.setContentType(mimeType);
    response.setContentLength((int) downloadFile.length());

    // set headers for the response
    String headerKey = "Content-Disposition";
    String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
    response.setHeader(headerKey, headerValue);

    OutputStream outStream = response.getOutputStream();

    byte[] buffer = new byte[4096];
    int bytesRead = -1;

    // write bytes read from the input stream into the output stream
    while ((bytesRead = inputStream.read(buffer)) != -1) {
      outStream.write(buffer, 0, bytesRead);
    }

    inputStream.close();
    outStream.close();

    //
    //					//ServletOutputStream out = response.getOutputStream();
    //					FileOutputStream fos = new FileOutputStream(downloadFile);
    //						System.out.println("Adding " + downloadFile.getName());
    //
    //						// Get the file
    //						FileInputStream fis = null;
    //						try {
    //							fis = new FileInputStream(downloadFile);
    //
    //						} catch (FileNotFoundException fnfe) {
    //							// If the file does not exists, write an error entry instead of
    //							// file
    //							// contents
    //							fos.write(("ERROR could not find file " + downloadFile.getName())
    //									.getBytes());
    //							fos.close();
    //							System.out.println("Couldfind file "
    //									+ downloadFile.getAbsolutePath());
    //						}
    //
    //						BufferedInputStream fif = new BufferedInputStream(fis);
    //
    //						// Write the contents of the file
    //						int data = 0;
    //						while ((data = fif.read()) != -1) {
    //							fos.write(data);
    //						}
    //						fif.close();
    //
    //						fos.close();
    System.out.println("Finished Downloading file " + downloadFile.getName());
    return;
    // return "redirect:extUserHomePage";
  }
  @RequestMapping(value = "/transfer_money", method = RequestMethod.POST)
  public String transfermoneyPageAction(
      @ModelAttribute("transferOp") TempTransactions transObj, Model model, HttpSession session)
      throws Exception {
    logger.info("Inside transfer money op POST");
    @SuppressWarnings("deprecation")
    String uniqId = (String) session.getAttribute("uniqueid");

    /** To display user profile */
    UserInfo UI = new UserInfo();
    DatabaseConnectors dbcon = new DatabaseConnectors();
    UI = dbcon.getUserInfoByUniqId((String) session.getAttribute("uniqueid"));

    String utype = null;
    String str1 = (String) session.getAttribute("uniqueid");
    System.out.println(str1);
    String str2 = str1.substring(0, 2);

    if (str2.equals("ei")) {
      utype = "Single User";
    } else if (str2.equals("em")) {
      utype = "Merchant";
    } else if (str2.equals("ir")) {
      utype = "Internal User";
    } else if (str2.equals("im")) {
      utype = "Manager";
    } else if (str2.equals("admin")) {
      utype = "Administrator";
    }

    ExternalUser extUser = databaseConnector.getExternalUserByUniqId(uniqId);

    model.addAttribute("firstName", UI.getFirstName());
    model.addAttribute("lastName", UI.getLastName());
    model.addAttribute("Username", UI.getUsername());
    model.addAttribute("email", UI.getEmailId());
    model.addAttribute("accountno", extUser.getAccountno());
    model.addAttribute("streetAddress", UI.getAddress());
    model.addAttribute("city", UI.getCity());
    model.addAttribute("state", UI.getState());
    model.addAttribute("country", UI.getCountry());
    model.addAttribute("zip", UI.getZipcode());
    model.addAttribute("contactNo", UI.getContactNo());
    model.addAttribute("userType", utype);

    MultipartFile fileGot = transObj.getMpFile();
    String file_name = fileGot.getOriginalFilename();

    ServletContext context = session.getServletContext();
    String realContextPath = context.getRealPath("/");

    //	            String certpath = realContextPath+"/certificates/"+fileGot.getOriginalFilename();
    String certpath = realContextPath + "/certificates/" + uniqId + "_cert.pem";

    String temp__2_2 = realContextPath + "/certificates";
    File temp_1_2 = new File(temp__2_2);
    if (!temp_1_2.exists()) temp_1_2.mkdirs();

    File convFile = new File(certpath);
    convFile.createNewFile();
    FileOutputStream fos = new FileOutputStream(convFile);
    fos.write(fileGot.getBytes());
    fos.close();

    if (pkiGringott.verifyCertificate(uniqId, session) == false) {
      logger.info(certpath);
      logger.info("uniqId is:" + uniqId);
      logger.info("Certificate verification is failed");
      model.addAttribute("message", "Certificate verification failed");

      Transactions transObj_1 = new Transactions();
      //					logger.info("Ext User"+extUser);
      // transObj.setBalance(extUser.getBalance());

      TempTransactions temp_1 = new TempTransactions();
      temp_1.setBalance(transObj.getBalance());

      model.addAttribute("debitOp", transObj_1);
      model.addAttribute("creditOp", transObj_1);
      model.addAttribute("checkAccBal", transObj_1.getBalance());

      model.addAttribute("transferOp", temp_1);
      model.addAttribute("paymerchantOp", temp_1);
      model.addAttribute("UpdateProfile", new UserInfo());

      List<Transactions> obj_1 = displaytransaction(session);
      if (obj_1 == null) {
        model.addAttribute("transactionOp", null);
      } else {
        model.addAttribute("transactionOp", obj_1);
      }

      return "extUserHomePage";
    } else {
      logger.info("uniqId is:" + uniqId);
      logger.info("Certificate verified");
    }

    MultipartFile pkf = transObj.getPkFile();

    String pkf_name = pkf.getOriginalFilename();
    logger.info(pkf_name);

    //				String pkpath = realContextPath+"/privatekeys/"+pkf.getOriginalFilename();
    String pkpath = realContextPath + "/privatekeys/" + uniqId + "_private.key";

    String temp_1 = realContextPath + "/privatekeys";
    File temp_1_1 = new File(temp_1);
    if (!temp_1_1.exists()) temp_1_1.mkdirs();

    File convFile_1 = new File(pkpath);

    convFile_1.createNewFile();
    FileOutputStream fos_1 = new FileOutputStream(convFile_1);
    fos_1.write(pkf.getBytes());
    fos_1.close();

    if (pkiGringott.verifyPrivateKey(uniqId, session) == false) {
      logger.info(pkpath);
      logger.info("uniqId is:" + uniqId);
      logger.info("private key verification is failed");
      model.addAttribute("message", "private key verification failed");

      Transactions transObj_2 = new Transactions();
      //					logger.info("Ext User"+extUser);
      // transObj.setBalance(extUser.getBalance());

      TempTransactions temp_2 = new TempTransactions();
      temp_2.setBalance(transObj.getBalance());

      model.addAttribute("debitOp", transObj_2);
      model.addAttribute("creditOp", transObj_2);
      model.addAttribute("checkAccBal", transObj_2.getBalance());

      model.addAttribute("transferOp", temp_2);
      model.addAttribute("paymerchantOp", temp_2);
      model.addAttribute("UpdateProfile", new UserInfo());

      List<Transactions> obj_2 = displaytransaction(session);
      if (obj_2 == null) {
        model.addAttribute("transactionOp", null);
      } else {
        model.addAttribute("transactionOp", obj_2);
      }

      return "extUserHomePage";
    } else {
      logger.info("uniqId is:" + uniqId);
      logger.info("Private key verified");
    }

    UserInfo extInfo = databaseConnector.getUserInfoByUniqId(extUser.getUniqId());

    session.setAttribute("transAccntNo", transObj.getAccountno());

    logger.info("Inside credit part of transfer money op POST");
    // String uniqueID = (String)session.getAttribute("uniqueid");
    // String uniqueID ="EM123";
    OtpTransactions transPost2 = new OtpTransactions();
    ExternalUser extUser2 = databaseConnector.getExternalUserByAccNum(transObj.getAccountno());
    OtpTransactions transPost = new OtpTransactions();
    transPost.setBalance(extUser.getBalance());
    transObj.setBalance(extUser.getBalance());
    float amount = transObj.getTransactionAmount();
    float currentBalance = transObj.getBalance();

    if (extUser2 == null) {
      model.addAttribute("message", "Account number not found");
      model.addAttribute("debitOp", transPost);
      model.addAttribute("creditOp", transPost);
      model.addAttribute("checkAccBal", extUser.getBalance());
      model.addAttribute("transferOp", transObj);
      model.addAttribute("paymerchantOp", transObj);
      model.addAttribute("UpdateProfile", new UserInfo());
      List<Transactions> obj = displaytransaction(session);
      if (obj == null) {
        model.addAttribute("transactionOp", null);
      } else {
        model.addAttribute("transactionOp", obj);
      }
      return "extUserHomePage";
    }

    databaseConnector.deleteOtpTransactionById(uniqId);
    databaseConnector.deleteOtpTransactionById(extUser2.getUniqId());

    if (currentBalance >= amount) {
      logger.info("EU.getBalance" + transPost.getBalance());
      // debit amount from current account balance
      transPost.setUniqId(uniqId);
      transPost.setDescription("debited amount: " + amount);
      transPost.setTransactionAmount(amount);
      transPost.setTransactionType("debit");
      transPost.setBalance(currentBalance - amount);

      // extUser.setBalance(currentBalance-amount);
      // databaseConnector.updateExternalUser(extUser);
      databaseConnector.saveOtpTransaction(transPost);

      session.setAttribute("recipient", extUser2.getUniqId().toString());
      float currentBalance1 = extUser2.getBalance();
      logger.info("Current Balance" + currentBalance1);
      transPost2.setBalance(extUser.getBalance());
      logger.info("balance :" + currentBalance1);
      // credit amount from current account balance
      transPost2.setUniqId(extUser2.getUniqId());
      transPost2.setDescription("credited amount: " + amount);
      transPost2.setTransactionAmount(amount);
      transPost2.setTransactionType("credit");
      transPost2.setBalance(currentBalance1 + amount);
      // extUser2.setBalance(currentBalance1+amount);
      // databaseConnector.updateExternalUser(extUser2);
      databaseConnector.saveOtpTransaction(transPost2);

      model.addAttribute("debitOp", transPost);
      model.addAttribute("creditOp", transPost);
      model.addAttribute("checkAccBal", extUser.getBalance());
      model.addAttribute("transferOp", transObj);
      model.addAttribute("paymerchantOp", transObj);
      model.addAttribute("UpdateProfile", new UserInfo());
      List<Transactions> obj = displaytransaction(session);
      if (obj == null) {
        model.addAttribute("transactionOp", null);
      } else {
        model.addAttribute("transactionOp", obj);
      }

    } else {
      model.addAttribute("message", "Amount cannot be more than the balance");
    }
    Random rand = new Random();
    int randomNum = rand.nextInt(737568) + 256846;
    String IV = Integer.toString(randomNum);
    System.out.println("Random number (IV): " + IV);

    String app1Hash;
    String app1Password;

    // counter starts at 0 - no clicks yet
    int app1Counter = 0;

    Hashtable<String, Integer> h = new Hashtable<String, Integer>();

    // do first run with intialization vector
    GenerateOtp firstApp = new GenerateOtp();
    app1Hash = firstApp.genHash(IV);
    app1Password = firstApp.genPassword(app1Hash);

    System.out.println(IV);
    for (int i = 0; i < 1; i++) {
      app1Hash = firstApp.genHash(app1Hash); // send old hash as seed for next sha hash
      app1Password =
          firstApp.genPassword(app1Hash); // new OTP will be calculated using the new hash

      if (!h.containsKey(app1Password)) {
        h.put(app1Password, 0);
        app1Counter++;
      }
      System.out.println("app1 OTP: " + app1Password);
      System.out.println(app1Counter);
    }
    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.socketFactory.port", "465");
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.port", "465");

    Session session1 =
        Session.getDefaultInstance(
            props,
            new javax.mail.Authenticator() {
              protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("*****@*****.**", "softwaresecurity");
              }
            });

    try {

      Message message = new MimeMessage(session1);
      message.setFrom(new InternetAddress("*****@*****.**"));
      message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(extInfo.getEmailId()));
      message.setSubject("One Time Password - Gringotts Bank");
      message.setText(
          "Dear User,"
              + "\n\n OTP for your account is as follows:"
              + " "
              + app1Password
              + "."
              + "\n\n Regards,"
              + "\n\n Gringotts Bank");

      Transport.send(message);

    } catch (MessagingException e) {
      throw new RuntimeException(e);
    }

    /* code for sending otp on button click ends here */

    /* Code for saving OTP */

    DateFormat dateFormat1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    Date date1 = new Date();
    String initdate = dateFormat1.format(date1);

    long t = date1.getTime();
    Date afterAddingTenMins = new Date(t + (10 * ONE_MINUTE_IN_MILLIS));
    String exptime = dateFormat1.format(afterAddingTenMins);

    String username = session.getAttribute("username").toString();

    // System.out.println(dateFormat1.format(date1)); //2014/08/06 15:59:48

    OneTimePass l = new OneTimePass(username, initdate, exptime, Integer.parseInt(app1Password));
    DatabaseConnectors d = new DatabaseConnectors();

    d.deleteOtpByUsername(username);
    d.saveOTP(l);

    /* CODE FOR SAVING OTP */

    logger.info("Leaving transfer money POST");
    return "redirect:confirmOtp";
  }