package registration;

import java.sql.*;
import java.rmi.*;
import java.rmi.server.*;
import java.util.Properties;
import java.util.*;

public class RegistrationServer extends UnicastRemoteObject 
			implements RegistrationHome {
    RegistrationServer() throws RemoteException {
        super();
    }

    public Connection getConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:jdc:jdcpool");
    }

    public registration.RegistrationPK create(String theuser, 
			String password, String emailaddress, 
			String creditcard) 
			throws registration.CreateException{
        
        double balance=0;
        Connection con = null;
        PreparedStatement ps = null;

        try {
           con=getConnection();
           ps=con.prepareStatement("insert into registration(
			theuser, password, emailaddress, 
			creditcard, balance) values (?, ?, ?, ?, ?)");
           ps.setString(1, theuser);
           ps.setString(2, password);
           ps.setString(3, emailaddress);
           ps.setString(4, creditcard);
           ps.setDouble(5, balance);
           
           if (ps.executeUpdate() != 1) {
               throw new CreateException ();
           }
           RegistrationPK primaryKey = new RegistrationPK();
           primaryKey.setUser(theuser);
           return primaryKey;
       } catch (CreateException ce) {
          throw ce;
       } catch (SQLException sqe) {
          throw new CreateException ();
       } finally {
          try {
             ps.close();
            con.close();
          } catch (Exception ignore) {
          }
       }
    }

    public registration.Registration findByPrimaryKey(
		registration.RegistrationPK pk) 
		throws registration.FinderException {
        if ((pk == null) || (pk.getUser() == null)) {
            throw new FinderException ();
        }
        return(refresh(pk));
    }

    private Registration refresh(RegistrationPK pk)
                      throws FinderException {

        if (pk == null) {
            throw new FinderException ();
        }
        Connection con = null;
        PreparedStatement ps = null;
        try {
           con=getConnection();
           ps=con.prepareStatement("select password, 
		emailaddress, creditcard, 
		balance from registration where theuser = ?");
           ps.setString(1, pk.getUser());
           ps.executeQuery();
           ResultSet rs = ps.getResultSet();
           if (rs.next()) {
              RegistrationImpl reg=null;
              try {
                 reg= new RegistrationImpl();
              }catch (RemoteException e) {}
              reg.theuser = pk.getUser();
              reg.password = rs.getString(1);
              reg.emailaddress = rs.getString(2);
              reg.creditcard = rs.getString(3);
              reg.balance = rs.getDouble(4);
              return reg;
           }
           else {
               throw new FinderException ();
           }
       }
       catch (SQLException sqe) {
           throw new FinderException();
       }
       finally {
          try {
             ps.close();
             con.close();
          }
          catch (Exception ignore) {}
       }
    }

    public void findLowCreditAccounts(final ReturnResults client)  
		throws FinderException {
        Runnable bgthread = new Runnable() {
           public void run() {
              Connection con = null;
              ResultSet rs = null;
              PreparedStatement ps = null;
              ArrayList ar = new ArrayList();

               try {
                    con=getConnection();
                    ps=con.prepareStatement("select theuser, 
			balance from registration where balance < ?");
                    ps.setDouble(1, 3.00);
                    ps.executeQuery();
                    rs = ps.getResultSet();
                    RegistrationImpl reg=null;
                    while (rs.next()) {
                        try {
                           reg= new RegistrationImpl();
                        }catch (RemoteException e) {}
                        reg.theuser = rs.getString(1);
                        reg.balance = rs.getDouble(2);
                        ar.add(reg);
                    }
                    rs.close();
                    client.updateResults(ar);
                 }catch (Exception e) {
                     System.out.println("findLowCreditAccounts: "+e);
                     return;
                 }
                 finally {
                    try {
                       if(rs != null) {
                           rs.close();
                       }
                       if(ps != null) {
                           ps.close();
                       }
                       if(con != null) {
                           con.close();
                       }
                    } catch (Exception ignore) {}
                 }
             } //run
         };
         Thread t = new Thread(bgthread);
         t.start();
    }
   
    public static void main(String args[]) {

        try {
        new pool.JDCConnectionDriver("postgresql.Driver", 
		"jdbc:postgresql:ejbdemo","postgres", "pass");
	}catch (Exception e){}
        try {
           Properties env=System.getProperties(); 
           env.put("java.rmi.server.codebase", "file:/root/book/"); 
           RegistrationServer rs= new RegistrationServer();
           if (System.getSecurityManager() == null )  {
              System.setSecurityManager(new RMISecurityManager());
           }
           Naming.rebind("//localhost/registration2",rs);
        }catch (Exception e) {
           System.out.println("Exception thrown "+e);
        }
   }
}

class RegistrationImpl extends UnicastRemoteObject 
		implements Registration {
    public String theuser, password, creditcard, emailaddress;
    public double balance;

    RegistrationImpl() throws RemoteException {
        super();
    }

    public boolean verifyPassword(String password) {
        if (this.password.equals(password)) {
            return true;
        } else {
            return false;
        }
    }

    public String getEmailAddress() {
        return emailaddress;
    }

    public String getUser() {
        return theuser;
    }

    public int adjustAccount(double amount) {
        balance=balance+amount;
        return(0);
    }

    public double getBalance() {
        return balance;
    }
}