package auction;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.naming.*;
import javax.ejb.*;
import java.rmi.RemoteException;
import java.util.*;
import java.text.NumberFormat;
import bidder.*;
import registration.*;
import seller.*;
import pool.*;
import search.*;

public class AuctionServlet extends HttpServlet {

    javax.naming.Context ctx=null;

    public void init(ServletConfig config) throws ServletException{
	super.init(config);
        try {
            ctx = getInitialContext();
        }catch (Exception e){
           System.err.println("failed to contact EJB server"+e);
	}
        Properties env=System.getProperties();
        env.put("java.rmi.server.codebase", "file:/root/book/");
        env.put("java.security.policy","/root/book/policy");
    }

    public void service(HttpServletRequest request, 
                HttpServletResponse response) throws IOException {

        String cmd;
        response.setContentType("text/html");
        ServletOutputStream out = response.getOutputStream();
        if (ctx == null ) {
	   try {
               ctx = getInitialContext();
           }catch (Exception e){
               System.err.println("failed to contact EJB server"+e);
	   }
	}

        cmd=request.getParameter("action"); 
        if(cmd !=null)  {
            if(cmd.equals("list")) {
		 listAllItems(out);
            }
            else if(cmd.equals("newlist")) {
		 listAllNewItems(out);
            }
            else if(cmd.equals("search")) {
		 searchItems(out, request);
            }
            else if(cmd.equals("close")) {
		 listClosingItems(out);
            }
            else if(cmd.equals("insert")) {
		 insertItem(out, request);
            }
            else if (cmd.equals("details")) {
		 itemDetails(out, request );
            }
            else if (cmd.equals("bid")) {
		 itemBid(out, request) ;
            }
            else if (cmd.equals("auditAccounts")) {
		 auditAccounts(out, request);
            }
            else if (cmd.equals("register")) {
		 registerUser(out, request);
	    }
        }
        else {
           // no command set
	   setTitle(out, "error");
        }
	setFooter(out);
        out.flush();
    }


    static private void addLine(String message, ServletOutputStream out) 
             throws IOException {
        if(message !=null) {
           out.println("<BR>"+message);
        }
    }

    static public javax.naming.Context getInitialContext() throws Exception {
        Properties p = new Properties();
        p.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
          "weblogic.jndi.TengahInitialContextFactory");
        return new InitialContext(p);
    }

    private void listAllItems(ServletOutputStream out) throws IOException{

        String text = "Click Item number for description and to place bid.";
	setTitle(out, "Auction results");
        try {
            addLine("<BR>"+text, out);
            BidderHome bhome=(BidderHome) ctx.lookup("bidder");
            Bidder bid=bhome.create();
            Enumeration enum=(Enumeration)bid.getItemList();

            if(enum != null) {
                displayitems(enum, out);
                addLine("", out);
            }
        } catch (Exception e) {
             addLine("AuctionServlet List All Items error",out);
             System.out.println("AuctionServlet <list>:"+e);
        }
        out.flush();
    }

    private void listAllNewItems(ServletOutputStream out) throws IOException {

        setTitle(out, "New Auction Items");
        try {
            addLine("", out);
            String text = "Click Item number for description and to place bid.";
            addLine(text, out);
            BidderHome bhome=(BidderHome) ctx.lookup("bidder");
            Bidder bid=bhome.create();
            Enumeration enum=(Enumeration)bid.getNewItemList();

            if(enum != null) {
                displayitems(enum, out);
                addLine("", out);
            }
         } catch (Exception e) {
             addLine("AuctionServlet List New Items error", out);
             System.out.println("AuctionServlet <newlist>:"+e);
         }
         out.flush();
    }

    private void searchItems(ServletOutputStream out, 
                  HttpServletRequest request) throws IOException {

        String searchString=request.getParameter("searchString");
        String text = "Click Item number for description and to place bid.";
        setTitle(out, "Search Results");
        try {
            addLine("<BR>"+text, out);
            AuctionItemHome ahome = (AuctionItemHome) ctx.lookup("auctionitems");
            SearchHome shome=(SearchHome) ctx.lookup("search");
            Search search=shome.create();
            Enumeration enum=(Enumeration)
                              search.getMatchingItemsList(searchString);

            addLine("<TABLE BORDER=1 CELLPADDING=1 CELLSPACING=0><TR><TH>Item</TH><TH>Summary</TH><TH>Current High bid</TH><TH>Number of bids</TH><TH>Closing Date</TH></TR>", out);
            while ((enum != null) && (enum.hasMoreElements())) {
                while(enum.hasMoreElements()) {
                    AuctionItem ai=ahome.findByPrimaryKey((AuctionItemPK)enum.nextElement());
                    displayLineItem(ai, out);
                }
            }
            addLine("</TABLE>", out);
        } catch (Exception e) {
             addLine("AuctionServlet Search Items error", out);
             System.out.println("AuctionServlet <searchItems>:"+e);
        }
        out.flush();
    }

    private void listClosingItems(ServletOutputStream out)  throws IOException{
        setTitle(out, "Items Due to Close Today");
        String text = "Click Item number for description and to place bid.";
        setTitle(out, "Items Due to Close Today");
        try {
            addLine("<BR>"+text, out);
            BidderHome bhome=(BidderHome) ctx.lookup("bidder");
            Bidder bid=bhome.create();
            Enumeration enum=(Enumeration)bid.getClosedItemList();

            if(enum != null) {
                 displayitems(enum, out);
                 addLine("", out);
	    }
        } catch (Exception e) {
             addLine("AuctionServlet List Closed Items error", out);
             System.out.println("AuctionServlet <close>:"+e);
        }
        out.flush();
    }

    private void insertItem(ServletOutputStream out, HttpServletRequest request) throws IOException{

        setTitle(out, "Insert Auction Item");
        String seller=request.getParameter("seller");
        String description=request.getParameter("description");
        String summary=request.getParameter("summary");
        String password=request.getParameter("password");
        String price=request.getParameter("startprice");
        double startprice=0.00;
        try{
            startprice=((Number)NumberFormat.getCurrencyInstance(Locale.US).parse("$"+price)).doubleValue();
        }catch(java.text.ParseException e){
            System.out.println("money problem"+e);
	    return;
	}catch (NumberFormatException e) {
             System.out.println("money problem"+e);
	     return;
        }

        int auctiondays=7;
        try{
           auctiondays=Integer.parseInt(request.getParameter("auctiondays"));
        } catch(NumberFormatException e){
             System.out.println("problem parsing auction days"+e);
	     return;
        }

        if(auctiondays<=0 || auctiondays>7) {
            auctiondays=7;
        }

        try {
            SellerHome home = (SellerHome) ctx.lookup("seller");
            Seller si= home.create();

            if(si != null) {
                int result= si.insertItem(seller, password, description, 
                                         auctiondays, startprice, summary);
                if (result >0) {
                    addLine("Inserted item "+summary, out);
                    addLine("Details available <A HREF=/AuctionServlet?action=details&item="+result+">here</A>", out);
                }
                else {
                    addLine("Error inserting item", out);
		    return;
                }
                addLine("", out);
	    }
       } catch (Exception e) {
            addLine("AuctionServlet Insert Item error", out);
            System.out.println("AuctionServlet <insert>:"+e);
       }
       out.flush();
    }


    private void itemDetails(ServletOutputStream out, HttpServletRequest request) throws IOException{

        setTitle(out, "Item Details");
        String item=request.getParameter("item");
        int itemid=0;

        try {
            itemid=Integer.parseInt(item);
        }catch (NumberFormatException e) {
	    System.out.println("problem with item id "+itemid);
	    return;
        }

        try {
            AuctionItemHome home = (AuctionItemHome) ctx.lookup("auctionitems");
            AuctionItemPK pk=new AuctionItemPK();
            pk.id=itemid;

            AuctionItem ai=home.findByPrimaryKey(pk);
            displayPageItem(ai, out);
            addLine("<BR><HR><P>Do you want to bid on this item?", out);
            addLine("<FORM ACTION=\"/AuctionServlet\" METHOD=\"POST\">", out);
            addLine("<TR>Enter your user id:<INPUT TYPE=\"TEXT\" SIZE=20 NAME=\"buyer\"> ", out);
            addLine("and password:<INPUT TYPE=\"PASSWORD\" SIZE=20 NAME=\"password\"></TR>", out);
            addLine("<TR>Your bid amount:<INPUT TYPE=\"TEXT\" SIZE=20 NAME=\"amount\"></TR>", out);
            addLine("<INPUT TYPE=\"HIDDEN\" NAME=\"action\" VALUE=\"bid\">", out);
            addLine("<INPUT TYPE=\"HIDDEN\" NAME=\"item\" VALUE=\""+itemid+"\">", out);
            addLine("<INPUT TYPE=\"SUBMIT\" VALUE=\"Place Bid\" NAME=\"Bid\"></FORM>", out);

        } catch (Exception e) {
             addLine("AuctionServlet List Item error", out);
             System.out.println("AuctionServlet <details>:"+e);
        }
        out.flush();
    }

    private void itemBid(ServletOutputStream out, HttpServletRequest request) throws IOException{

        setTitle(out, "Item Bid");
        String item=request.getParameter("item");
        String buyer=request.getParameter("buyer");
        String password=request.getParameter("password");
        String bid=request.getParameter("amount");
        int itemid=0;
        double bidamount=0;

        try {
            itemid=Integer.parseInt(item);
        }catch (NumberFormatException e) {
            System.out.println("problem with item id " +itemid);
	    return;
        }

        try {
            bidamount=Double.valueOf(bid).doubleValue();
        }catch (NumberFormatException e) {
            System.out.println("problem with bid" +bid);
	    return;
        }

        try {
            BidderHome bhome = (BidderHome) ctx.lookup("bidder");
            Bidder bidbean=bhome.create();
            int result=bidbean.placeBid(itemid, buyer, password, bidamount);
            switch(result) {
	        case Auction.OUT_BID:
                         addLine("Your bid was not high enough", out);
                         break;
                case Auction.HIGH_BID:
                         addLine("You are the high bidder", out);
                         break;
                case Auction.AUCTION_OVER:
                         addLine("This auction has finished", out);
                         break;
                case Auction.INVALID_USER:
                         addLine("Invalid user or password", out);
                         break;
                default:  
                         addLine("Problem submitting bid", out);
             }

         } catch (Exception e) {
             addLine("AuctionServlet Bid error", out);
             System.out.println("AuctionServlet <bid>:"+e);
         }
        out.flush();
    }

    private void registerUser(ServletOutputStream out, HttpServletRequest request) throws IOException{

       String user=request.getParameter("user");
       String password=request.getParameter("password");
       String creditcard=request.getParameter("creditcard");
       String emailaddress=request.getParameter("emailaddress");
       try {

          RegistrationHome regRef = (RegistrationHome)java.rmi.Naming.lookup("//localhost/registration2");
          RegistrationPK reguser = regRef.create(user, password, emailaddress, creditcard);
          if(reguser != null) {
              addLine("Created user: "+reguser.getUser(),out);
              addLine("", out);
           }
           else {
              addLine("Error creating user id, possibly already exists ", out);
           }
       } catch(Exception e) {
           addLine("AuctionServlet registration error", out);
           System.out.println("AuctionServlet <register>:"+e.toString());
       }
       out.flush();
    }

    private void auditAccounts(ServletOutputStream out, 
               HttpServletRequest request) throws IOException{

        String text = "Audit of users with low credit.";
        String remoteaddr =request.getHeader("REMOTE_ADDR");

	setTitle(out, "Audit Accounts");
        if(!remoteaddr.equals("127.0.0.1")) {
           addLine("service not available", out);
        }
        try {
            addLine("<BR>"+text, out);
            addLine("<TABLE BORDER=1 CELLPADDING=1 CELLSPACING=0><TR><TH>User</TH><TH>Accounts Balance</TH></TR>", out);
            SellerHome home = (SellerHome) ctx.lookup("seller");
            Seller si= home.create();

            if(si != null) {
                ArrayList ar=si.auditAccounts();
                for(Iterator i=ar.iterator(); i.hasNext();) {
                  Registration user=(Registration)(i.next());
                  addLine("<TD>"+user.getUser()+"</TD><TD>"+user.getBalance()+"</TD></TR>", out); 
                }
	        addLine("</TABLE>", out);
            }
        } catch (Exception e) {
             addLine("AuctionServlet auditAccounts error",out);
             System.out.println("AuctionServlet <auditAccounts>:"+e);
        }
        out.flush();
    }

    static private void displayitems(Enumeration e, 
                                ServletOutputStream out) throws Exception{

        addLine("<TABLE BORDER=1 CELLPADDING=1 CELLSPACING=0><TR><TH>Item</TH><TH>Summary</TH><TH>Current High bid</TH><TH>Number of bids</TH><TH>Closing Date</TH></TR>", out);
        while((e !=null) && (e.hasMoreElements())) {
            while(e.hasMoreElements()) {
                displayLineItem((AuctionItem) e.nextElement(), out);
            }
        }
	addLine("</TABLE>", out);
    }

    static private void displayLineItem(AuctionItem auctionItem, ServletOutputStream out)
                        throws RemoteException, IOException {

        StringBuffer line= new StringBuffer();
	int bidcount=auctionItem.getBidCount();

        int key=(int)auctionItem.getId();
        line.append("<TR><TD><A HREF=/AuctionServlet?action=details&item="+key+">"+key+"</A></TD>");
        line.append("<TD>"+auctionItem.getSummary() +"</TD>");
        if(bidcount >0) {
            line.append("<TD>"+NumberFormat.getCurrencyInstance().format(auctionItem.getHighBid()) +"</TD>");
        }
        else {
            line.append("<TD>-</TD>");
        }
            line.append("<TD>"+bidcount+"</TD>");
    
        line.append("<TD>"+auctionItem.getEndDate() +"</TD></TR>");
        addLine(line.toString(), out);
    }

    static private void displayPageItem(AuctionItem auctionItem, ServletOutputStream out)
                        throws RemoteException, IOException {

        int bidcount=auctionItem.getBidCount();
        addLine(auctionItem.getSummary(), out);
        addLine("Auction Item Number: "+auctionItem.getPrimaryKey(), out);
        if(bidcount >0) {
            addLine("<P>Current price: "+NumberFormat.getCurrencyInstance().format(auctionItem.getHighBid()), out);
            addLine("Minimum increment: "+NumberFormat.getCurrencyInstance().format(auctionItem.getIncrement()), out);
        }
        else {
            addLine("<P>Current price: "+NumberFormat.getCurrencyInstance().format(auctionItem.getStartPrice()), out);
        }
        addLine("# of bids: "+bidcount, out);
    
        addLine("<P>Auction Started: "+auctionItem.getStartDate(), out);
        addLine("Auction Ends: "+auctionItem.getEndDate(), out);
        addLine("<P>Seller: "+auctionItem.getSeller(), out);
        if(bidcount >0) {
            addLine("High Bidder: "+auctionItem.getHighBidder(), out);
        } else {
            addLine("High Bidder: "+"-", out);
        }
        addLine("<HR><P>", out);
        addLine("Description: "+auctionItem.getDescription(), out);
    }

    private String readFile (String file) throws IOException {
	if (file != null) {
            StringBuffer buffer = new StringBuffer();
            BufferedReader reader = new BufferedReader (new FileReader (file));
            String line;
            while ( (line=reader.readLine()) != null ) {
                buffer.append (line+'\n');
            }
            reader.close();
            return buffer.toString();
	}
	else {
	    return null;
	}
    }
    private void setTitle(ServletOutputStream out, String title) {
	try { 
            out.println("<HTML><HEAD><TITLE>"+title+"</TITLE></HEAD>");
	    out.println("<BODY BGCOLOR=\"WHITE\">");
        } catch(IOException e) {
            System.out.println("Unable to set title"+e);
        }
    }

    private void setFooter(ServletOutputStream out) {
        try {
            out.println("<HR><CENTER> <A HREF=\"registration.html\">Register</A>");
            out.println("<STRONG>|</STRONG>");
            out.println("<A HREF=\"/AuctionServlet?action=newlist\">New Items</A>");
            out.println("<STRONG>|</STRONG>");
            out.println("<A HREF=\"/AuctionServlet?action=close\">Closing Items</A>");
            out.println("<STRONG>|</STRONG>");
            out.println("<A HREF=\"/AuctionServlet?action=list\">All Items</A>");
            out.println("<STRONG>|</STRONG>");
            out.println("<A HREF=\"sell.html\">Sell Items</A>");
            out.println("</CENTER>");

        } catch (IOException e) {
            System.out.println("Unable to set footer"+e);
        }
    }
}
