package com.acme.util.ui;


import com.acme.structure.exception.UnAuthorizedAccessException;
import com.acme.structure.exception.base.ApplicationException;
import com.acme.structure.exception.persistent.ConstraintException;
import com.acme.structure.exception.persistent.ReferentialConstraintException;
import com.acme.structure.exception.persistent.RequiredFieldEmptyException;
import com.acme.structure.exception.persistent.UniqueConstraintException;

import java.sql.BatchUpdateException;

import java.util.ArrayList;
import java.util.Collection;

import javax.ejb.EJBAccessException;
import javax.ejb.EJBException;

import javax.naming.NamingException;

import javax.persistence.EntityExistsException;
import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;

import org.hibernate.PropertyValueException;
import org.hibernate.exception.ConstraintViolationException;


public class ExceptionDispatcher implements ExceptionHandler
{
    public Collection handleException(Exception exc)
    {
        Collection userInformationList = new ArrayList();
        try
        {
            throw exc;
        }
        catch (ApplicationException handledException)
        {
            userInformationList.add(WindowManager.getInstance().getStatusUtil().checkedExceptionOccured(handledException));
        }
        catch (EJBAccessException handledException)
        {
            userInformationList.add(WindowManager.getInstance().getStatusUtil().checkedExceptionOccured(new UnAuthorizedAccessException()));
        }
        catch (NamingException handledException)
        {
            userInformationList.add(WindowManager.getInstance().getStatusUtil().criticalErrorOccured(handledException));
        }
        catch (Exception handledException)
        {
            Throwable temp = handledException;
            if (temp.getCause() == null)
                userInformationList.add(WindowManager.getInstance().getStatusUtil().criticalErrorOccured(exc));
            else
                while ((temp = temp.getCause()) != null)
                {
                    if (temp instanceof RollbackException && temp.getCause() instanceof EntityExistsException)
                    {
                        userInformationList.add(WindowManager.getInstance().getStatusUtil().checkedExceptionOccured(new UniqueConstraintException()));
                        break;
                    } else if (handledException instanceof EJBException)
                    {
                        // check for referential constraint
                        if (temp instanceof EntityExistsException)
                        {
                            userInformationList.add(WindowManager.getInstance().getStatusUtil().checkedExceptionOccured(new ReferentialConstraintException()));
                            break;
                        } else if (temp instanceof PersistenceException && temp.getCause() instanceof PropertyValueException &&
                                   ((PropertyValueException)temp.getCause()).getMessage().contains("not-null property"))
                        {
                            userInformationList.add(WindowManager.getInstance().getHandler().handleException(new RequiredFieldEmptyException(((PropertyValueException)temp.getCause()).getPropertyName())));
                            break;
                        } else if (temp instanceof PersistenceException && temp.getCause() instanceof ConstraintViolationException)
                        {
                            if (temp.getCause().getCause() instanceof BatchUpdateException && temp.getCause().getCause().toString().contains("unique constraint"))
                                userInformationList.add(WindowManager.getInstance().getStatusUtil().checkedExceptionOccured(new UniqueConstraintException(((ConstraintViolationException)temp.getCause()).getConstraintName())));
                            else
                                userInformationList.add(WindowManager.getInstance().getStatusUtil().checkedExceptionOccured(new ConstraintException(((ConstraintViolationException)temp.getCause()).getConstraintName())));
                        } else
                            userInformationList.add(WindowManager.getInstance().getStatusUtil().criticalErrorOccured(exc));
                    } else
                        userInformationList.add(WindowManager.getInstance().getStatusUtil().criticalErrorOccured(exc));
                }
        }

        return userInformationList;
    }

    public Collection handleExceptions(Collection exceptionList)
    {
        return WindowManager.getInstance().getStatusUtil().checkedExceptionsOccured(exceptionList);
        /*
		Iterator<Exception> itr=exc.iterator();
		
		while(itr.hasNext())
			handleException(itr.next());
		 */
    }

}
