/*
 * 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.subclassing.ejb;

import jakarta.ejb.*;
import javax.naming.*;
import java.sql.*;
import javax.sql.DataSource;

public class CustomerEJB implements jakarta.ejb.EntityBean
{
  //database fields
  String SSN;
  String firstName;
  String lastName;
  String address1;
  String address2;
  String city;
  String state;
  String zipCode;
  long savingsBalance;
  long checkingBalance;
  EntityContext ejbContext = null;
  InitialContext ic = null;
  DataSource dataSource = null;

  public static final String SAVINGS = "savings";
  public static final String CHECKING = "checking";

  public String getFirstName()
  {
    return firstName;
  }

  public String getLastName()
  {
    return lastName;
  }

  public String getAddress1()
  {
    return address1;
  }

  public String getAddress2()
  {
    return address2;
  }

  public String getCity()
  {
    return city;
  }

  public String getState()
  {
    return state;
  }

  public String getZipCode()
  {
    return zipCode;
  }

  public String getSSN()
  {
    return this.SSN;
  }

  public long getSavingsBalance()
  {
    return savingsBalance;
  }

  public long getCheckingBalance()
  {
    return checkingBalance;
  }

  public void doCredit(long amount, String accountType)
  {
    if (accountType.equals(SAVINGS) && amount>0)
      this.savingsBalance = this.savingsBalance + amount + 1;
    else if (accountType.equals(CHECKING))
      this.checkingBalance = this.checkingBalance + amount;
  }

  public void doDebit(long amount, String accountType)
  {
    if (accountType.equals(SAVINGS))
      this.savingsBalance = this.savingsBalance - amount;
    else if (accountType.equals(CHECKING))
      this.checkingBalance = this.checkingBalance - amount;
  }

  public void setEntityContext(EntityContext cntx)
  {
    ejbContext = cntx;
    try {
    ic = new InitialContext();
    dataSource = (DataSource)ic.lookup("java:comp/env/jdbc/SimpleBank");
    } catch (NamingException e) {
      System.out.println("Naming exception occured while trying to lookup the datasource");
      e.printStackTrace();
    }
  }

  public void unsetEntityContext()
  {
    ejbContext = null;
  }

  public void ejbRemove()
  {
    System.out.println("In ejbRemove method");
    try {
    Connection conn = null;
      conn = dataSource.getConnection();
      String primaryKey = (String)ejbContext.getPrimaryKey();
      Statement statement = conn.createStatement();
      String query = "DELETE FROM customer2 where SSN = '" + primaryKey + "'";
      statement.executeUpdate(query);
      conn.close();
      } catch (SQLException e) {
        System.out.println("SQL exception occured in ejbRemove method");
        e.printStackTrace();
      }

  }

  public void ejbStore()
  {
    System.out.println("In ejbStore method");
    System.out.println("SavingsBalance = " + this.savingsBalance);
    System.out.println("CheckingBalance = " + this.checkingBalance);
    try {
    Connection conn = null;
      String primaryKey = (String)ejbContext.getPrimaryKey();
      System.out.println("Primarykey = " + primaryKey);
      conn = dataSource.getConnection();
      PreparedStatement statement = null;
      statement = conn.prepareStatement(
        "UPDATE customer2 " +
        "set lastName = ?, firstName = ?, address1 = ?, address2 = ?, " +
        "city = ?, state = ?, zipCode = ?, savingsBalance = ?, checkingBalance = ? " +
        "where SSN = ?"
      );
      statement.setString(1, this.lastName);
      statement.setString(2, this.firstName);
      statement.setString(3, this.address1);
      statement.setString(4, this.address2);
      statement.setString(5, this.city);
      statement.setString(6, this.state);
      statement.setString(7, this.zipCode);
      statement.setLong(8, this.savingsBalance);
      statement.setLong(9, this.checkingBalance);
      statement.setString(10, primaryKey);
      statement.executeUpdate();
      conn.close();
      } catch (SQLException e) {
        System.out.println("SQL exception occured in ejbStore method");
        e.printStackTrace();
      }

  }

  public void ejbLoad()
  {
    try {
    Connection conn = null;
    String primaryKey = (String)ejbContext.getPrimaryKey();
    conn = dataSource.getConnection();
    Statement statement = conn.createStatement();
    String query = "SELECT * FROM customer2 where SSN = '" + primaryKey + "'";
    ResultSet results = statement.executeQuery(query);
    if (results.next())
    {
      this.SSN = results.getString("SSN");
      this.lastName = results.getString("lastName");
      this.firstName = results.getString("firstName");
      this.address1 = results.getString("address1");
      this.address2 = results.getString("address2");
      this.city = results.getString("city");
      this.state = results.getString("state");
      this.zipCode = results.getString("zipCode");
      this.savingsBalance = results.getLong("savingsBalance");
      this.checkingBalance = results.getLong("checkingBalance");
    } else {
      System.out.println("ERROR!! No entry matching the entered Social Security Number!");
    }
    conn.close();
    } catch (SQLException e) {
      System.out.println("SQLException occurred in ejbLoad() method");
      e.printStackTrace();
    }
  }

  public void ejbActivate() {}
  public void ejbPassivate() {}
}



