/**
 * 
 */


package gov.va.med.cds.idm.client;


import gov.va.med.cds.exception.ErrorCodeEnum;
import gov.va.med.cds.exception.IdmPersonServiceCreateException;
import gov.va.med.cds.exception.IdmPersonServiceException;
import gov.va.med.cds.idm.client.webservice.PSIMWebServiceLocator;
import gov.va.med.cds.idm.client.webservice.PSIMWebServicePort;
import gov.va.med.cds.util.EndpointResolver;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.hibernate.service.spi.ServiceException;

import java.net.MalformedURLException;
import java.net.URL;


/**
 * @author susarlan
 * 
 */
public class IdmPersonServiceFactory
{
    private String serviceBindingId = null;

    private EndpointResolver endpointResolver = null;


    public synchronized IdmPersonServiceInterface create( Integer idmWebserviceTimeoutSecs )
    {

        try
        {
            IdmPersonServiceDelegate delegate = new IdmPersonServiceDelegate();
            PSIMWebServicePort idmWebservicePort = getBusinessDelegate( idmWebserviceTimeoutSecs );
            delegate.setIdmService( idmWebservicePort );

            return delegate;

        }
        catch ( Exception ex )
        {
            throw new IdmPersonServiceCreateException( "Could not create a business delegate via Caip.", ex );
        }
    }


    private PSIMWebServicePort getBusinessDelegate( Integer idmWebserviceTimeoutSecs )
        throws ServiceException
    {
        try
        {
            URL endpoint = new URL( endpointResolver.resolve( serviceBindingId ) );

            String endPointAsString = endpoint.toString();

            if ( null != endPointAsString && !endPointAsString.contains( "?" ) )
            {
                try
                {
                    endpoint = new java.net.URL( endPointAsString + "?wsdl" );

                }
                catch ( MalformedURLException e )
                {
                    throw new Exception( e );
                }
            }

            PSIMWebServiceLocator psimWsLocator = new PSIMWebServiceLocator( endpoint, new javax.xml.namespace.QName( "PSIM", "PSIMWebService" ) );

            PSIMWebServicePort port = ( PSIMWebServicePort )psimWsLocator.getPSIMWebServicePort();

            if ( idmWebserviceTimeoutSecs != null )
            {
                Client client = ClientProxy.getClient( port );
                HTTPConduit http = ( HTTPConduit )client.getConduit();

                HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();

                httpClientPolicy.setConnectionTimeout( idmWebserviceTimeoutSecs );
                httpClientPolicy.setAllowChunking( false );
                httpClientPolicy.setReceiveTimeout( idmWebserviceTimeoutSecs );

                http.setClient( httpClientPolicy );

            }
            return port;

        }
        catch ( Exception e )
        {
            throw new IdmPersonServiceException( ErrorCodeEnum.IDM_SERVICE_EXCEPTION, e, "Error finding service in registry." );
        }
    }


    public void setEndpointResolver( EndpointResolver endpointResolver )
    {
        this.endpointResolver = endpointResolver;
    }


    public void setServiceBindingId( String serviceBindingId )
    {
        this.serviceBindingId = serviceBindingId;
    }

}
