/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package samples.ejb.installed_libraries_embedded.servlet;

import java.io.*;
import java.util.*;
import jakarta.servlet.*;
import javax.naming.*;
import jakarta.servlet.http.*;
import jakarta.ejb.*;

import samples.ejb.installed_libraries_embedded.ejb.*;
import com.sun.jdbcra.spi.JdbcSetupAdmin;

public class SimpleBankServlet extends HttpServlet {


  InitialContext initContext = null;
  CustomerSavingsLocalHome customerSavingsLocalHome = null;
  CustomerCheckingLocalHome customerCheckingLocalHome = null;
  CustomerSavings customerSavings = null;
  CustomerChecking customerChecking = null;
  Hashtable env = new java.util.Hashtable(1);
  String JNDIName = null;
  Object objref = null;

  public void init()
  {
  }

  public void doGet (HttpServletRequest request,HttpServletResponse response)
        throws ServletException, IOException {
    doPost(request, response);
  }

  /** handles the HTTP POST operation **/
  public void doPost (HttpServletRequest request,HttpServletResponse response)
        throws ServletException, IOException {
    doLookup();
    System.out.println("SimpleBankServlet is executing");
    String SSN = request.getParameter("SSN");

    String message = "";
    String jsp = "";
    String lastName = "";
    String firstName = "";
    String address1 = "";
    String address2 = "";
    String city = "";
    String state = "";
    String zipCode = "";
    long currentSavingsBalance = 0;
    long currentCheckingBalance = 0;

    String action = request.getParameter("action");
    if (action.equals("Create"))
    {
      message = "Add Customer";
      jsp = "/SimpleBankAdd.jsp";
    }
    else if (action.equals("Add Customer"))
    {
      System.out.println("Add Customer button pressed");
      SSN = request.getParameter("SSN");
      lastName = request.getParameter("lastName");
      firstName = request.getParameter("firstName");
      address1 = request.getParameter("address1");
      address2 = request.getParameter("address2");
      city = request.getParameter("city");
      state = request.getParameter("state");
      zipCode = request.getParameter("zipCode");

      try {
        System.out.println("Creating the customer savings remote bean");
        customerSavings = customerSavingsLocalHome.create(SSN, lastName, firstName, address1, address2, city, state, zipCode);
      } catch (Exception e) {
        System.out.println("Could not create the customer savings remote bean : " + e.toString());
        throw new ServletException(e.getMessage());
        //return;
      }
      message = "Customer Added.";
      jsp = "/SimpleBankMessage.jsp";
    }
    else if (action.equals("Edit"))
    {
      try {
        System.out.println("Finding the customer savings remote bean");
        customerSavings = customerSavingsLocalHome.findByPrimaryKey(SSN);
      } catch (Exception e) {
        System.out.println("Could not find the customer remote bean : " + e.toString());
        throw new ServletException(e.getMessage());
        //return;
      }
      jsp = "/SimpleBankEdit.jsp";
    }
    else if (action.equals("Delete"))
    {
      try {
        System.out.println("Finding the customer savings remote bean");
        customerSavings = customerSavingsLocalHome.findByPrimaryKey(SSN);
      } catch (Exception e) {
        System.out.println("Could not find the customer savings remote bean : " + e.toString());
        throw new ServletException(e.getMessage());
        //return;
      }
      message = "Delete Customer";
      jsp = "/SimpleBankDelete.jsp";
    }
    else if (action.equals("Delete Customer"))
    {
      try {
        customerSavingsLocalHome.findByPrimaryKey(SSN).remove();
      } catch (Exception e) {
        System.out.println("Could not delete the customer savings bean : " + e.toString());
        throw new ServletException(e.getMessage());
        //return;
      }
      message = "Customer Deleted.";
      jsp = "/SimpleBankMessage.jsp";
    }


    else if (action.equals("Update"))
    {
      try {
        System.out.println("Finding the customersavings remote bean");
        customerSavings = (CustomerSavings)customerSavingsLocalHome.findByPrimaryKey(SSN);
      } catch (Exception e) {
        System.out.println("Could not find the customer savings remote bean : " + e.toString());
        throw new ServletException(e.getMessage());
        //return;
      }

      try {
        System.out.println("Finding the customerchecking remote bean");
        customerChecking = (CustomerChecking)customerCheckingLocalHome.findByPrimaryKey(SSN);
      } catch (Exception e) {
        System.out.println("Could not find the customer checking remote bean : " + e.toString());
        throw new ServletException(e.getMessage());
        //return;
      }

      System.out.println("Transaction Complete");
      String operationSavings = request.getParameter("operationSavings");
      System.out.println("operationSavings = " + operationSavings);
      String operationChecking = request.getParameter("operationChecking");
      System.out.println("operationChecking = " + operationChecking);
      String amountSavings = request.getParameter("amountSavings");
      String amountChecking = request.getParameter("amountChecking");
      if (operationSavings.equals("credit"))
      {
        customerSavings.doCredit(Long.parseLong(amountSavings), CustomerEJB.SAVINGS);
        customerChecking.doCredit(Long.parseLong(amountSavings), CustomerEJB.SAVINGS);
      } else {
        customerSavings.doDebit(Long.parseLong(amountSavings), CustomerEJB.SAVINGS);
        customerChecking.doDebit(Long.parseLong(amountSavings), CustomerEJB.SAVINGS);
      }
      if (operationChecking.equals("credit"))
      {
        customerChecking.doCredit(Long.parseLong(amountChecking), CustomerEJB.CHECKING);
        customerSavings.doCredit(Long.parseLong(amountChecking), CustomerEJB.CHECKING);
      } else {
        customerChecking.doDebit(Long.parseLong(amountChecking), CustomerEJB.CHECKING);
        customerSavings.doDebit(Long.parseLong(amountChecking), CustomerEJB.CHECKING);
      }
      jsp = "/SimpleBankEdit.jsp";
    }

    if (customerSavings != null)
    {
      lastName = customerSavings.getLastName();
      firstName = customerSavings.getFirstName();
      address1 = customerSavings.getAddress1();
      address2 = customerSavings.getAddress2();
      city = customerSavings.getCity();
      state = customerSavings.getState();
      zipCode = customerSavings.getZipCode();
      SSN = customerSavings.getSSN();
      currentSavingsBalance = customerSavings.getSavingsBalance();
      currentCheckingBalance = customerSavings.getCheckingBalance();
    }

    System.out.println("storing the values in the request object");
    request.setAttribute("lastName", lastName);
    request.setAttribute("firstName", firstName);
    request.setAttribute("address1", address1);
    request.setAttribute("address2", address2);
    request.setAttribute("city", city);
    request.setAttribute("state", state);
    request.setAttribute("zipCode", zipCode);
    request.setAttribute("SSN", SSN);
    request.setAttribute("currentSavingsBalance", String.valueOf(currentSavingsBalance));
    request.setAttribute("currentCheckingBalance", String.valueOf(currentCheckingBalance));
    request.setAttribute("message", message);
    response.setContentType("text/html");
    RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(jsp);
    dispatcher.include(request, response);
    return;
  }

  public void doLookup()
  {
    try {
      initContext = new javax.naming.InitialContext();
    } catch (Exception e) {
      System.out.println("Exception occured when creating InitialContext: " + e.toString());
      return;
    }

    try {
      JdbcSetupAdmin ja = (JdbcSetupAdmin) initContext.lookup("eis/jdbcAdmin");
      if (ja.checkSetup() == false) {
         throw new RuntimeException("JDBC Setup Wroing");
      }
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e.getMessage());
    }

    try {
      System.out.println("Looking up customer savings bean home interface");
      JNDIName = "java:comp/env/ejb/customerSavings";
      System.out.println("Looking up: " + JNDIName);
      objref = initContext.lookup(JNDIName);
      //customerSavingsLocalHome = (CustomerSavingsLocalHome)PortableRemoteObject.narrow(objref, CustomerSavingsLocalHome.class);
      customerSavingsLocalHome = (CustomerSavingsLocalHome)objref;
    } catch (Exception e) {
      System.out.println("Customer savings bean home not found - Is the bean registered with JNDI? : " + e.toString());
      return;
    }

    try {
      System.out.println("Looking up customer checking bean home interface");
      JNDIName = "java:comp/env/ejb/customerChecking";
      System.out.println("Looking up: " + JNDIName);
      objref = initContext.lookup(JNDIName);
      //customerCheckingLocalHome = (CustomerCheckingLocalHome)PortableRemoteObject.narrow(objref, CustomerCheckingLocalHome.class);
      customerCheckingLocalHome = (CustomerCheckingLocalHome)objref;
    } catch (Exception e) {
      System.out.println("Customer checking bean home not found - Is the bean registered with JNDI? : " + e.toString());
      return;
    }
  }
}
