/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas.jtests.clients.entity;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.objectweb.jonas.jtests.beans.ejbql.*;
import org.objectweb.jonas.jtests.util.JTestCase;

public class F_ConEnlist extends JTestCase {

    private static SessionTestHomeRemote sessiontesthome = null;
    private static CustomerHomeRemote customerhome = null;
    private static ReservationHomeRemote reservationhome = null;
    private static CruiseHomeRemote cruisehome = null;
    private static ShipHomeRemote shiphome = null;
    private static CabinHomeRemote cabinhome = null;
    private static AddressHomeRemote addresshome = null;
    private static CreditCardHomeRemote creditcardhome = null;

    private boolean initialized = false;

    public F_ConEnlist(String name) {
        super(name);
    }

    protected void setUp() {
        super.setUp();
        if (! useBeans("ejbql", false)) {
            if (!initialized) {
                // The bean was already loaded by another test.
                // Clean the tables first.
                try {
                    tearDown();
                } catch (Exception e) {
                    System.out.println("cannot init tables");
                }
            }
        }
    }

    protected void tearDown() throws Exception {
        Collection c = getShipHome().findAllShips();
        for (Iterator i = c.iterator(); i.hasNext();) {
            ShipRemote s = (ShipRemote) PortableRemoteObject.narrow(i.next(), ShipRemote.class);
            s.remove();
        }
        c = getReservationHome().findAllReservations();
        for (Iterator i = c.iterator(); i.hasNext();) {
            ReservationRemote s = (ReservationRemote) PortableRemoteObject.narrow(i.next(), ReservationRemote.class);
            s.remove();
        }
        c = getCruiseHome().findAllCruises();
        for (Iterator i = c.iterator(); i.hasNext();) {
            CruiseRemote s = (CruiseRemote) PortableRemoteObject.narrow(i.next(), CruiseRemote.class);
            s.remove();
        }
        c = getCustomerHome().findCustomersAll();
        for (Iterator i = c.iterator(); i.hasNext();) {
            CustomerRemote s = (CustomerRemote) PortableRemoteObject.narrow(i.next(), CustomerRemote.class);
            s.remove();
        }
        for (int dl = 1; dl <= 7; dl++) {
            c = getCabinHome().findAllOnDeckLevel(new Integer(dl));
            for (Iterator i = c.iterator(); i.hasNext();) {
                CabinRemote s = (CabinRemote) PortableRemoteObject.narrow(i.next(), CabinRemote.class);
                s.remove();
            }
        }
    }

    private SessionTestHomeRemote getSessionTestHome() throws Exception {
        if (sessiontesthome == null) {
            sessiontesthome  = (SessionTestHomeRemote)
                PortableRemoteObject.narrow(ictx.lookup("EjbqlSessionTestHomeRemote"),
                                            SessionTestHomeRemote.class);
        }
        assertTrue(sessiontesthome != null);
        return sessiontesthome;
    }

    private CustomerHomeRemote getCustomerHome() throws Exception {
        if (customerhome == null) {
            customerhome  = (CustomerHomeRemote)
                PortableRemoteObject.narrow(ictx.lookup("CustomerHomeRemote"),
                                            CustomerHomeRemote.class);
        }
        assertTrue(customerhome != null);
        return customerhome;
    }

    private ShipHomeRemote getShipHome() throws Exception {
        if (shiphome == null) {
            shiphome  = (ShipHomeRemote)
                PortableRemoteObject.narrow(ictx.lookup("ShipHomeRemote"),
                                            ShipHomeRemote.class);
        }
        assertTrue(shiphome != null);
        return shiphome;
    }

    private CruiseHomeRemote getCruiseHome() throws Exception {
        if (cruisehome == null) {
            cruisehome  = (CruiseHomeRemote)
                PortableRemoteObject.narrow(ictx.lookup("CruiseHomeRemote"),
                                            CruiseHomeRemote.class);
        }
        assertTrue(cruisehome != null);
        return cruisehome;
    }

    private ReservationHomeRemote getReservationHome() throws Exception {
        if (reservationhome == null) {
            reservationhome  = (ReservationHomeRemote)
                PortableRemoteObject.narrow(ictx.lookup("ReservationHomeRemote"),
                                            ReservationHomeRemote.class);
        }
        assertTrue(reservationhome != null);
        return reservationhome;
    }

    private CabinHomeRemote getCabinHome() throws Exception {
        if (cabinhome == null) {
            cabinhome  = (CabinHomeRemote)
                PortableRemoteObject.narrow(ictx.lookup("CabinHomeRemote"),
                                            CabinHomeRemote.class);
        }
        assertTrue(cabinhome != null);
        return cabinhome;
    }

    private AddressHomeRemote getAddressHome() throws Exception {
        if (addresshome == null) {
            addresshome  = (AddressHomeRemote)
                PortableRemoteObject.narrow(ictx.lookup("AddressHomeRemote"),
                                            AddressHomeRemote.class);
        }
        assertTrue(addresshome != null);
        return addresshome;
    }

    public void test1() throws Exception {
        utx.begin();
        ShipRemote shipA = getShipHome().create(new Integer(10772), "Ship A", 30000.0);
        CruiseRemote cruiseA = getCruiseHome().create("Cruise A", new Integer(10772));
        utx.commit();
    }

    public void test2() throws Exception {
        utx.begin();
        ShipRemote shipA = getShipHome().create(new Integer(10772), "Ship A", 30000.0);
        CruiseRemote cruiseA = getCruiseHome().create("Cruise A", new Integer(10772));
        for (int j = 1; j <= 10; j++) {
            getShipHome().create(new Integer(j), "Ship " + j, 30000.0 + (10000.0 * j));
        }
        utx.commit();
    }

    public void test3() throws Exception {
        utx.begin();
        ShipRemote shipA = getShipHome().create(new Integer(10772), "Ship A", 30000.0);
        CruiseRemote cruiseA = getCruiseHome().create("Cruise A", new Integer(10772));
        for (int j = 1; j <= 10; j++) {
            getShipHome().create(new Integer(j), "Ship " + j, 30000.0 + (10000.0 * j));
        }
        ShipRemote ship1 = getShipHome().findByPrimaryKey(new Integer(1));
        cruiseA = getCruiseHome().create("Alaska Cruise", new Integer(1));
        CruiseRemote cruiseB = getCruiseHome().create("Bohemian Cruise", new Integer(1));
        for (int i = 80; i <= 99; i++) {
            CustomerRemote customer = getCustomerHome().create(new Integer(i));
            customer.setName(new Name("Smith" + i, "John"));
            customer.addPhoneNumber("612-555-12" + i, (byte) 1);
            customer.setAddress("10" + i + " Elm Street", "LONDON", "MN", "5540");
            customer.setHasGoodCredit(i % 4 == 0);
            if (i % 4 == 0) {
                customer.setCreditCard(new Date(), "100001" + i, "MasterCard", "CA" ,
                                       "CETELEM", "rue de jeunet", "PARIS", "France",  "3888" );
            }
        }
        utx.commit();
    }

    public void test4() throws Exception {
        utx.begin();
        ShipRemote shipA = getShipHome().create(new Integer(10772), "Ship A", 30000.0);
        CruiseRemote cruiseA = getCruiseHome().create("Cruise A", new Integer(10772));
        for (int j = 1; j <= 10; j++) {
            getShipHome().create(new Integer(j), "Ship " + j, 30000.0 + (10000.0 * j));
        }
        ShipRemote ship1 = getShipHome().findByPrimaryKey(new Integer(1));
        cruiseA = getCruiseHome().create("Alaska Cruise", new Integer(1));
        CruiseRemote cruiseB = getCruiseHome().create("Bohemian Cruise", new Integer(1));
        for (int i = 80; i <= 99; i++) {
            CustomerRemote customer = getCustomerHome().create(new Integer(i));
            customer.setName(new Name("Smith" + i, "John"));
            customer.addPhoneNumber("612-555-12" + i, (byte) 1);
            customer.setAddress("10" + i + " Elm Street", "LONDON", "MN", "5540");
            customer.setHasGoodCredit(i % 4 == 0);
            if (i % 4 == 0) {
                customer.setCreditCard(new Date(), "100001" + i, "MasterCard", "CA" ,
                                       "CETELEM", "rue de jeunet", "PARIS", "France",  "3888" );
            }
        }
        Calendar date = Calendar.getInstance();
        date.set(2004, 04, 01);
        for (int i = 201; i <= 207; i++) {
            Collection customers = new ArrayList();
            CustomerRemote cust = getCustomerHome().create(new Integer(i));
            cust.setName(new Name("Customer "+i,"Mike"));
            cust.setHasGoodCredit(i % 2 == 0);
            cust.setAddress("50"+i+" Main Street","Minneapolis","MN","5510"+i);
            customers.add(new Integer(i));  // put this single customer in the collection

            Collection reservations = new ArrayList();
            for (int j = 0; j < 2; j++) {
                ReservationRemote reservation = getReservationHome().create(cruiseA.getId(), customers);
                reservation.setDate(date.getTime());
                reservation.setAmountPaid(1000*i + 100*j + 2000);
                date.add(Calendar.DAY_OF_MONTH, 7);

                Set cabins = new HashSet();
                CabinRemote cabin = getCabinHome().create(new Integer(1000+i*100+j));
                cabin.setDeckLevel(i - 200);
                cabin.setName("Cabin "+ i + "0" + j + "1");
                cabins.add(cabin.getId());
                cabin = getCabinHome().create(new Integer(1000+i*100+10+j));
                cabin.setDeckLevel(i - 200);
                cabin.setName("Cabin "+i+"0"+j+"2");
                cabins.add(cabin.getId());
                reservation.setAllCabins(cabins);  // this reservation has 2 cabins
            }
        }
        utx.commit();
    }

    public void test35() throws Exception {
        utx.begin();
        ShipRemote shipA = getShipHome().create(new Integer(10772), "Ship A", 30000.0);
        CruiseRemote cruiseA = getCruiseHome().create("Cruise A", new Integer(10772));
        for (int j = 1; j <= 10; j++) {
            getShipHome().create(new Integer(j), "Ship " + j, 30000.0 + (10000.0 * j));
        }
        ShipRemote ship1 = getShipHome().findByPrimaryKey(new Integer(1));
        cruiseA = getCruiseHome().create("Alaska Cruise", new Integer(1));
        CruiseRemote cruiseB = getCruiseHome().create("Bohemian Cruise", new Integer(1));
        for (int i = 80; i <= 99; i++) {
            CustomerRemote customer = getCustomerHome().create(new Integer(i));
            customer.setName(new Name("Smith" + i, "John"));
            customer.addPhoneNumber("612-555-12" + i, (byte) 1);
            customer.setAddress("10" + i + " Elm Street", "LONDON", "MN", "5540");
            customer.setHasGoodCredit(i % 4 == 0);
            if (i % 4 == 0) {
                customer.setCreditCard(new Date(), "100001" + i, "MasterCard", "CA" ,
                                       "CETELEM", "rue de jeunet", "PARIS", "France",  "3888" );
            }
        }
        Calendar date = Calendar.getInstance();
        date.set(2004, 04, 01);
        int i = 201;
        Collection customers = new ArrayList();
        CustomerRemote cust = getCustomerHome().create(new Integer(i));
        cust.setName(new Name("Customer "+i,"Mike"));
        cust.setHasGoodCredit(i % 2 == 0);
        cust.setAddress("50"+i+" Main Street","Minneapolis","MN","5510"+i);
        customers.add(new Integer(i));  // put this single customer in the collection

        Collection reservations = new ArrayList();
        int j = 0;
        ReservationRemote reservation = getReservationHome().create(cruiseA.getId(), customers);
        reservation.setDate(date.getTime());
        reservation.setAmountPaid(1000*i + 100*j + 2000);
        date.add(Calendar.DAY_OF_MONTH, 7);

        Set cabins = new HashSet();
        CabinRemote cabin = getCabinHome().create(new Integer(1000+i*100+j));
        cabin.setDeckLevel(i - 200);
        cabin.setName("Cabin "+ i + "0" + j + "1");
        cabins.add(cabin.getId());
        cabin = getCabinHome().create(new Integer(1000+i*100+10+j));
        cabin.setDeckLevel(i - 200);
        cabin.setName("Cabin "+i+"0"+j+"2");
        cabins.add(cabin.getId());
        reservation.setAllCabins(cabins);  // this reservation has 2 cabins
        utx.commit();
    }

    public void test33() throws Exception {
        utx.begin();
        ShipRemote shipA = getShipHome().create(new Integer(10772), "Ship A", 30000.0);
        CruiseRemote cruiseA = getCruiseHome().create("Cruise A", new Integer(10772));
        for (int j = 1; j <= 10; j++) {
            getShipHome().create(new Integer(j), "Ship " + j, 30000.0 + (10000.0 * j));
        }
        ShipRemote ship1 = getShipHome().findByPrimaryKey(new Integer(1));
        cruiseA = getCruiseHome().create("Alaska Cruise", new Integer(1));
        CruiseRemote cruiseB = getCruiseHome().create("Bohemian Cruise", new Integer(1));
        for (int i = 80; i <= 82; i++) {
            CustomerRemote customer = getCustomerHome().create(new Integer(i));
            customer.setName(new Name("Smith" + i, "John"));
            customer.addPhoneNumber("612-555-12" + i, (byte) 1);
            customer.setAddress("10" + i + " Elm Street", "LONDON", "MN", "5540");
            customer.setHasGoodCredit(i % 4 == 0);
            if (i % 4 == 0) {
                customer.setCreditCard(new Date(), "100001" + i, "MasterCard", "CA" ,
                                       "CETELEM", "rue de jeunet", "PARIS", "France",  "3888" );
            }
        }
        utx.commit();

        utx.begin();
        Calendar date = Calendar.getInstance();
        date.set(2004, 04, 01);
        int i = 201;
        Collection customers = new ArrayList();
        CustomerRemote cust = getCustomerHome().create(new Integer(i));
        cust.setName(new Name("Customer "+i,"Mike"));
        cust.setHasGoodCredit(i % 2 == 0);
        cust.setAddress("50"+i+" Main Street","Minneapolis","MN","5510"+i);
        customers.add(new Integer(i));  // put this single customer in the collection
        utx.commit();

        utx.begin();
        Collection reservations = new ArrayList();
        int j = 0;
        ReservationRemote reservation = getReservationHome().create(cruiseA.getId(), customers);
        reservation.setDate(date.getTime());
        reservation.setAmountPaid(1000*i + 100*j + 2000);
        date.add(Calendar.DAY_OF_MONTH, 7);

        CabinRemote cabin = getCabinHome().create(new Integer(1000+i*100+j));
        cabin.setDeckLevel(i - 200);
        cabin.setName("Cabin "+ i + "0" + j + "1");
        cabin = getCabinHome().create(new Integer(1000+i*100+10+j));
        cabin.setDeckLevel(i - 200);
        cabin.setName("Cabin "+i+"0"+j+"2");
        utx.commit();
    }

    public void test11() throws Exception {
        test3();
        for (int i = 0; i < 10; i++) {
            Collection c = getShipHome().findAllShips();
        }
    }

    public void test100() throws Exception {

        // check if tables have been initialized
        try {
            getCustomerHome().findByPrimaryKey(new Integer(80));
        } catch (Exception e) {
            // Make the initialization needed for the tests
            try {
                utx.begin();
                String cities[] = new String[6];
                cities[0] = "Minneapolis"; cities[1] = "St. Paul"; cities[2] = "Rochester";
                cities[3] = "Winona"; cities[4] = "Wayzata"; cities[5] = "Eagan";
                ShipRemote shipA = getShipHome().create(new Integer(10772), "Ship A", 30000.0);
                CruiseRemote cruiseA = getCruiseHome().create("Cruise A", new Integer(10772));
                for (int jj = 1; jj <= 10; jj++) {
                    ShipRemote ship = getShipHome().create(new Integer(jj), "Ship " + jj, 30000.0 + (10000.0 * jj));
                }
                cruiseA = null;
                CruiseRemote cruiseB = null;
                ShipRemote ship1 = getShipHome().findByPrimaryKey(new Integer(1));
                cruiseA = getCruiseHome().create("Alaska Cruise", new Integer(1));
                cruiseB = getCruiseHome().create("Bohemian Cruise", new Integer(1));
                for (int kk = 80; kk <= 99; kk++) {
                    CustomerRemote customer = null;

                    customer = getCustomerHome().create(new Integer(kk));
                    customer.setName(new Name("Smith"+kk,"John") );
                    customer.addPhoneNumber("612-555-12"+kk,(byte) 1);

                    customer.setAddress("10"+kk+" Elm Street",
                                        cities[(kk-80)%6],
                                        (kk%2==0?"MN":"CA"),
                                        "5540"+(kk%5+1));
                    customer.setHasGoodCredit((kk%4 == 0));
                    if (kk%4 == 0)
                        customer.setCreditCard(new Date(System.currentTimeMillis()+100000), "100001"+kk, "MasterCard", "CA" ,"CETELEM", "rue de jeunet", cities[0], "France",  "3888" );
                }
                // Creating Customers 1-6, each with 2 reservations for 2 cabins
                Calendar date = Calendar.getInstance();
                date.set(2002,10,1);

                for (int kk=201; kk<207; kk++) {
                    Collection customers = new ArrayList();
                    CustomerRemote cust = getCustomerHome().create(new Integer(kk));
                    cust.setName(new Name("Customer "+kk,"Mike"));
                    cust.setHasGoodCredit( (kk%2==0) );  // odds are bums
                    cust.setAddress("50"+kk+" Main Street","Minneapolis","MN","5510"+kk);
                    customers.add(new Integer(kk));  // put this single customer in the collection

                    Collection reservations = new ArrayList();

                    for (int jj=0; jj<2; jj++) {

                        ReservationRemote reservation = getReservationHome().create(cruiseA.getId(), customers);
                        reservation.setDate(date.getTime());
                        reservation.setAmountPaid(1000*kk+100*jj+2000);

                        date.add(Calendar.DAY_OF_MONTH, 7);

                        Set cabins = new HashSet();
                        CabinRemote cabin = getCabinHome().create(new Integer(1000+kk*100+jj));
                        cabin.setDeckLevel(kk-200);
                        cabin.setName("Cabin "+kk+"0"+jj+"1");

                        cabins.add(cabin.getId());
                        cabin = getCabinHome().create(new Integer(1000+kk*100+10+jj));
                        cabin.setDeckLevel(kk-200);
                        cabin.setName("Cabin "+kk+"0"+jj+"2");

                        cabins.add(cabin.getId());

                        reservation.setAllCabins(cabins);  // this reservation has 2 cabins

                    }
                }
                String fnames[] = new String[5];
                fnames[0]="John"; fnames[1]="Paul"; fnames[2]="Ringo";
                fnames[3]="Joe"; fnames[4]="Roger";

                String lnames[] = new String[3];
                lnames[0]="Smith"; lnames[1]="Johnson"; lnames[2]="Star";
                // Creating Customers 50-69
                for (int kk=50; kk<=69; kk++) {
                    CustomerRemote customer = getCustomerHome().create(new Integer(kk));
                    customer.setName( new Name(lnames[(kk-50)%3], fnames[(kk-50)%5]) );
                    customer.addPhoneNumber("612-555-12"+kk,(byte)1);
                    customer.setAddress("10"+kk+" Elm Street",
                                        cities[(kk-50)%6],
                                        (kk%2==0?"MN":"CA"),
                                        "5540"+(kk%5+1));
                    customer.setHasGoodCredit((kk%4==0));

                    // Some customers will have reservations already on one of the two cruises..
                    if (kk%3!=0) {
                        Collection customers = new ArrayList();
                        customers.add(customer.getId());  // put this single customer in the collection
                        ReservationRemote reservation = getReservationHome().create((kk%3==1?cruiseA.getId():cruiseB.getId()), customers);
                        reservation.setDate(date.getTime());
                        reservation.setAmountPaid(10*kk+2000);
                        date.add(Calendar.DAY_OF_MONTH, 7);
                    }
                }

                // Creating Customers 100-109

                for (int kk=100; kk<=109; kk++) {
                    CustomerRemote customer = getCustomerHome().create(new Integer(kk));
                    customer.setName( new Name("Lennon"+kk, "Paul") );
                    customer.addPhoneNumber("666-543-12"+kk,(byte)1);

                    customer.setAddress("10"+kk+" Abbey Road",
                                        cities[(kk-100)%6],
                                        (kk%2==0?"FL":"WA"),
                                        "5540"+(kk%5+1));
                    customer.setHasGoodCredit((kk%4==0));
                }

            } catch (Exception i) {
                i.printStackTrace(System.out);
                fail("InitialState creation problem: "+i);
            } finally {
                try {
                    utx.commit();
                } catch (Exception ii) {
                }
            }
        }
    }




    public static Test suite() {
        return new TestSuite(F_ConEnlist.class);
    }

    public static void main (String args[]) {
        String testtorun = null;
        // Get args
        for (int argn = 0; argn < args.length; argn++) {
            String s_arg = args[argn];
            Integer i_arg;
            if (s_arg.equals("-n")) {
                testtorun = args[++argn];
            }
        }
        if (testtorun == null) {
            junit.textui.TestRunner.run(suite());
        } else {
            junit.textui.TestRunner.run(new F_ConEnlist(testtorun));
        }
    }
}

