package ejava.examples.checkouts.demo;

import ejava.examples.checkouts.ejb.*;
import ejava.examples.personnel.ejb20.*;

import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.ejb.EJBException;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Iterator;

public class Thread1EJB implements Thread1BI, SessionBean {
   static final long ONE_WEEK_MSECS = 1000*60*60*24*7;
   PersonLocalHome personLocalHome_;
   BorrowerLocalHome borrowerLocalHome_;
   CheckoutLocalHome checkoutLocalHome_;

   public String execute() throws DemoException {

      StringWriter out = new StringWriter();
      PrintWriter printer = new PrintWriter(out);
      try {

      personLocalHome_.create("0", "cat", "inhat", "here", "911");
      personLocalHome_.create("1", "thing", "one", "there", "911");
      personLocalHome_.create("2", "thing", "two", "everywhere", "911");

      PersonLocal person = 
         personLocalHome_.findByPrimaryKey(new PersonPK("1"));
      BorrowerLocal b1 = borrowerLocalHome_.create(person);
      printer.println("created borrower:" + b1.getName() +
         ", started=" + b1.getBeginDate() + ", ended=" + b1.getEndDate() + 
	 ", valid=" + b1.isValid());

      BorrowerLocal borrower = borrowerLocalHome_.findByPrimaryKey("1");
      Date now = new Date();
      CheckoutLocal co=null;
      co = checkoutLocalHome_.create(now);
      borrower.addCheckout(co);
      co = checkoutLocalHome_.create(new Date(now.getTime()-ONE_WEEK_MSECS*3));
      borrower.addCheckout(co);
      co = checkoutLocalHome_.create(new Date(now.getTime()-ONE_WEEK_MSECS*4));
      borrower.addCheckout(co);
      printer.println("last checkout="+co.getBorrower().getName() +
         ", checkouts=" + co.getBorrower().getCheckouts().size());

         //now try and perform a checkout to an invalid borrower
      PersonLocal catInHat = 
         personLocalHome_.findByPrimaryKey(new PersonPK("0"));
      borrower = borrowerLocalHome_.create(catInHat);
      borrower.terminate();
      co = checkoutLocalHome_.create(now);
      try {
         borrower.addCheckout(co);
      }
      catch (CheckoutException expected) {
         printer.println("could not checkout to " + borrower.getName() +
	    ":" + expected);
         co.remove();
      }

/**
**/
      return out.toString();

      }
      catch (Exception ex) {
         if (ex instanceof RuntimeException) throw (RuntimeException) ex;
         printer.println("---error---");
         throw new DemoException(out.toString() + ex.toString());
      }
   }

   public String status() throws DemoException {

      StringWriter out = new StringWriter();
      PrintWriter printer = new PrintWriter(out);
      try {
      printer.println("have the following users...");
      for(Iterator i=personLocalHome_.findAll().iterator(); i.hasNext(); ) {
         PersonLocal p = (PersonLocal)i.next();
	 printer.println(p.getFirstName() + " " + p.getLastName());
      }
      

      printer.println("have the following borrower(s)...");
      for(Iterator i=borrowerLocalHome_.findAll().iterator(); i.hasNext(); ) {
         BorrowerLocal b = (BorrowerLocal)i.next();
	 printer.println(b.getName() + ", checkouts=" +b.getCheckouts().size());
         for(Iterator j=b.getCheckouts().iterator(); j.hasNext(); ) {
	    CheckoutLocal co = (CheckoutLocal)j.next();
	    printer.println("\tcheckout: " + co.getOutDate() +
	                       ", overdue=" + co.isOverdue());
	 }
      }
      
      printer.println("have the following checkout(s)...");
      for(Iterator i=checkoutLocalHome_.findAll().iterator(); i.hasNext(); ) {
	 CheckoutLocal co = (CheckoutLocal)i.next();
	 BorrowerLocal borrower = co.getBorrower();
	 printer.println("\tcheckout: " + co.getOutDate() +
	    ", borrower=" +((borrower!=null) ? co.getBorrower().getName():"") +
	    ", overdue=" + co.isOverdue());
      }
      
      printer.println("have the following overdue checkout(s)...");
      for(Iterator i=checkoutLocalHome_.getOverdue().iterator(); i.hasNext();) {
	 CheckoutLocal co = (CheckoutLocal)i.next();
	 printer.println("\tcheckout: " + co.getOutDate() +
	                       ", borrower=" + co.getBorrower().getName() +
	                       ", overdue=" + co.isOverdue());
      }
/**
**/

      return out.toString();

      }
      catch (Exception ex) {
//         if (ex instanceof RuntimeException) throw (RuntimeException) ex;
         printer.println("---error---");
         throw new DemoException(out.toString() + ex.toString());
      }
      finally {
      }
   }

   public void cleanup() throws DemoException {
      try {
         for(Iterator i=personLocalHome_.findAll().iterator(); i.hasNext(); ) {
            PersonLocal p = (PersonLocal)i.next();
	    p.remove();
         }
      }
      catch (Exception ex) {
         throw new DemoException(ex.toString());
      }
   }

   public void ejbCreate() {
      try {
         Context jndi = new InitialContext();
         String context = (String)jndi.lookup("java:comp/env/PersonLocalHome");
	 personLocalHome_ = (PersonLocalHome)jndi.lookup(context);
         
	 context = (String)jndi.lookup("java:comp/env/BorrowerLocalHome");
	 borrowerLocalHome_ = (BorrowerLocalHome)jndi.lookup(context);
         
	 context = (String)jndi.lookup("java:comp/env/CheckoutLocalHome");
	 checkoutLocalHome_ = (CheckoutLocalHome)jndi.lookup(context);
      }
      catch (NamingException ex) {
         throw new EJBException("error initializing Thread1:" + ex.toString());
      }
   }
   public void ejbActivate() {}
   public void ejbPassivate() {}
   public void ejbRemove() {}
   public void setSessionContext(SessionContext ctx) {}
}
