package org.appfuse.service;

import java.util.Date;
import java.util.List;

import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.appfuse.model.Education;
import org.appfuse.model.Experience;
import org.appfuse.model.Membership;
import org.appfuse.model.Reference;
import org.appfuse.model.Resume;
import org.springframework.orm.hibernate.SessionFactoryUtils;
import org.springframework.orm.hibernate.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;

public class ResumeManagerTest extends BaseManagerTestCase {
    //~ Instance fields ========================================================

    private ResumeManager mgr = null;
    private Log log = LogFactory.getLog(ResumeManagerTest.class);
    private Resume resume;
    private SessionFactory sf;

    //~ Methods ================================================================

    protected void setUp() throws Exception {
        // the following is necessary for lazy loading
        sf = (SessionFactory) ctx.getBean("sessionFactory");
        // open and bind the session for this test thread.
        Session s = sf.openSession();
        TransactionSynchronizationManager.bindResource(sf, new SessionHolder(s));

        mgr = (ResumeManager) ctx.getBean("resumeManager");
    }

    protected void tearDown() throws Exception {
        // unbind and close the session.
        SessionHolder holder = (SessionHolder)
                TransactionSynchronizationManager.getResource(sf);
        if (holder != null) {
            Session s = holder.getSession();
            s.flush();
            TransactionSynchronizationManager.unbindResource(sf);
            SessionFactoryUtils.closeSessionIfNecessary(s, sf);
        }

        mgr = null;
    }

    public void testGetResumesForUser() throws Exception {
        List resumes = mgr.getResumesForUser("1");

        if (log.isDebugEnabled()) {
            log.debug(resumes);
        }

        assertTrue(resumes.size() > 0);
    }

    public void testGetResume() throws Exception {
        Resume resume = (Resume) mgr.getResume("1");

        if (log.isDebugEnabled()) {
            log.debug(resume);
        }

        assertTrue(resume.getName() != null);
    }

    public void testSaveResume() throws Exception {
        resume = (Resume) mgr.getResume("1");

        String original = resume.getDescription();
        resume.setDescription("UPDATED description");
        resume = (Resume) mgr.saveResume(resume);
        assertTrue(resume.getDescription().equals("UPDATED description"));

        // set to original value and save
        resume.setDescription(original);
        mgr.saveResume(resume);
    }

    public void testAddAndRemoveResume() throws Exception {
        resume = new Resume();
        resume.setDescription("description");
        resume.setName("simple test");
        resume.setObjective("objective");
        resume.setUserId(new Long(1));

        resume = (Resume) mgr.saveResume(resume);
        assertTrue(resume.getName().equals("simple test"));
        assertTrue(resume.getId() != null);

        if (log.isDebugEnabled()) {
            log.debug("removing resume...");
        }

        mgr.removeObject(resume);
    }

    public void testGetEducation() throws Exception {
        List list = mgr.getSchools("1");
        assertTrue(list.size() > 0);

        Education e = (Education) mgr.getEducation("1");
        assertTrue(e.getName() != null);
    }

    public void testAddAndRemoveEducation() throws Exception {
        Education e = new Education();
        e.setResumeId(new Long(1));
        e.setName("University of Colorado");
        e.setLocation("Boulder");
        e.setState("CO");
        e.setCountry("USA");
        e = (Education) mgr.saveObject(e);
        assertTrue(e.getId() != null);
        if (log.isDebugEnabled()) {
            log.debug("removing education...");
        }
        mgr.removeObject(e);
        e = (Education) mgr.getEducation(e.getId().toString());

        if (e != null) {
            fail("Education object found in database!");
        }
    }

    public void testGetExperience() throws Exception {
        List list = mgr.getWorkHistory("1");
        assertTrue(list.size() > 0);

        Experience e = (Experience) mgr.getExperience("1");
        assertTrue(e.getOrganizationName() != null);
    }

    public void testAddAndRemoveExperience() throws Exception {
        Experience e = new Experience();
        e.setResumeId(new Long(1));
        e.setOrganizationName("IBM Global Services");
        e.setLocation("Boulder");
        e.setTitle("Intranet Developer");
        e.setDescription("Helped develop intranet for CoBank.");

        // set dates
        Date startDate = new Date();
        startDate.setTime(startDate.getTime() - 2000000);
        e.setStartDate(startDate);
        Date endDate = new Date();
        endDate.setTime(endDate.getTime() + 1000000);
        e.setEndDate(endDate);

        if (log.isDebugEnabled()) {
            log.debug("saving... " + e);
        }
        e = (Experience) mgr.saveObject(e);
        log.debug("new id set to: " + e.getId());
        assertTrue(e.getId() != null);
        if (log.isDebugEnabled()) {
            log.debug("removing experience...");
        }
        mgr.removeObject(e);
        e = (Experience) mgr.getExperience(e.getId().toString());

        if (e != null) {
            fail("Experience object found in database!");
        }
    }

    public void testGetReference() throws Exception {
        List list = mgr.getReferences("1");
        assertTrue(list.size() > 0);

        Reference r = (Reference) mgr.getReference("1");
        assertTrue(r.getName() != null);
    }

    public void testAddAndRemoveReference() throws Exception {
        Reference ref = new Reference();
        ref.setResumeId(new Long(1));
        ref.setName("Alan VanNice");
        ref.setPhoneNumber("303-212-0591");
        ref.setProfessional(Boolean.TRUE);
        if (log.isDebugEnabled()) {
            log.debug("saving... " + ref);
        }
        ref = (Reference) mgr.saveObject(ref);
        log.debug("new id set to: " + ref.getId());
        assertTrue(ref.getId() != null);
        if (log.isDebugEnabled()) {
            log.debug("removing reference...");
        }
        mgr.removeObject(ref);
        ref = (Reference) mgr.getReference(ref.getId().toString());

        if (ref != null) {
            fail("Reference object found in database!");
        }
    }

    public void testGetMembership() throws Exception {
        List list = mgr.getMemberships("1");
        assertTrue(list.size() > 0);

        Membership mem = (Membership) mgr.getMembership("1");
        assertTrue(mem.getOrganizationName() != null);
    }

    public void testAddAndRemoveMembership() throws Exception {
        Membership mem = new Membership();
        mem.setResumeId(new Long(1));
        mem.setOrganizationName("Denver Chamber of Commerce");
        mem.setAffiliation("Member");
        Date startDate = new Date();
        startDate.setTime(startDate.getTime() - 2000000);
        mem.setStartDate(startDate);
        Date endDate = new Date();
        endDate.setTime(endDate.getTime() + 1000000);
        mem.setEndDate(endDate);

        if (log.isDebugEnabled()) {
            log.debug("saving... " + mem);
        }

        mem = (Membership) mgr.saveObject(mem);
        
        log.debug("new id set to: " + mem.getId());
        assertTrue(mem.getId() != null);
        if (log.isDebugEnabled()) {
            log.debug("removing membership...");
        }
        mgr.removeObject(mem);
        mem = (Membership) mgr.getMembership(mem.getId().toString());

        if (mem != null) {
            fail("Membership object found in database!");
        }
    }
    
    public static void main(String[] args) {
        junit.textui.TestRunner.run(ResumeManagerTest.class);
    }
}