package org.apache.savan.atom;

import com.wso2.eventing.atom.CreateFeedDocument;
import com.wso2.eventing.atom.CreateFeedDocument.CreateFeed;
import com.wso2.eventing.atom.CreateFeedResponseDocument;
import com.wso2.eventing.atom.CreateFeedResponseDocument.CreateFeedResponse;
import com.wso2.eventing.atom.FilterType;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.http.HttpStatus;
import org.apache.savan.SavanException;
import org.apache.savan.eventing.EventingConstants;
import org.apache.savan.filters.XPathBasedFilter;
import org.apache.savan.util.CommonUtil;
import org.apache.xmlbeans.XmlException;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Iterator;

/**
 * This class take provide client interface for Savan atom support
 *
 * @author Srinath Perera(hemapani@apache.org)
 */
public class AtomEventingClient {
    private ServiceClient serviceClient = null;

    private EndpointReference feedEpr;

    public AtomEventingClient(String serviceUrl, String clientRepository) throws AxisFault {
        ConfigurationContext configContext = ConfigurationContextFactory
                .createConfigurationContextFromFileSystem(clientRepository,
                                                          clientRepository + "/conf/axis2.xml");
        serviceClient = new ServiceClient(configContext, null); //TODO give a repo

        Options options = new Options();
        serviceClient.setOptions(options);
        serviceClient.engageModule(new QName("addressing"));
        options.setTo(new EndpointReference(serviceUrl));
    }


    public AtomEventingClient(ServiceClient serviceClient) {
        this.serviceClient = serviceClient;
    }

    public CreateFeedResponse createFeed(String title, String author)
            throws AxisFault {
        return createFeed(title, author, null, null);
    }

    public CreateFeedResponse createFeed(String title, String author,
                                         Calendar expiredTime, String xpathFilter)
            throws AxisFault {
        try {
            serviceClient.getOptions().setAction(
                    AtomConstants.Actions.Subscribe);

            CreateFeedDocument createFeedDocument = CreateFeedDocument.Factory
                    .newInstance();
            CreateFeed createFeed = createFeedDocument.addNewCreateFeed();

            createFeed.setAuthor(author);
            createFeed.setTitle(title);

            if (expiredTime != null) {
                createFeed.setExpires(expiredTime);
            }
            if (xpathFilter != null) {
                FilterType filter = createFeed.addNewFilter();
                filter.setDialect(XPathBasedFilter.XPATH_BASED_FILTER);
                filter.setStringValue(xpathFilter);
            }

            OMElement request = CommonUtil.toOM(createFeedDocument);
            request.build();
            OMElement element = serviceClient.sendReceive(request);
            CreateFeedResponseDocument createFeedResponseDocument =
                    CreateFeedResponseDocument.Factory
                            .parse(element.getXMLStreamReader());
            System.out.println(createFeedDocument.xmlText());

            // read epr for subscription from response and store it
            OMElement responseAsOM = CommonUtil
                    .toOM(createFeedResponseDocument);
            OMElement eprAsOM = responseAsOM.getFirstChildWithName(new QName(
                    AtomConstants.ATOM_MSG_NAMESPACE, "SubscriptionManager"));

            feedEpr = new EndpointReference(eprAsOM.getFirstElement().getText());
            OMElement referanceParameters = eprAsOM
                    .getFirstChildWithName(new QName(eprAsOM.getFirstElement()
                            .getNamespace().getNamespaceURI(),
                                                     AddressingConstants.EPR_REFERENCE_PARAMETERS));
            Iterator refparams = referanceParameters.getChildElements();
            while (refparams.hasNext()) {
                feedEpr.addReferenceParameter((OMElement)refparams.next());
            }

            return createFeedResponseDocument.getCreateFeedResponse();
        } catch (XmlException e) {
            throw AxisFault.makeFault(e);
        }
    }

    public void deleteFeed(EndpointReference epr) throws AxisFault {
        serviceClient.getOptions().setAction(AtomConstants.Actions.Unsubscribe);
        serviceClient.getOptions().setTo(epr);

        OMElement request = OMAbstractFactory.getOMFactory().createOMElement(
                new QName(AtomConstants.ATOM_MSG_NAMESPACE, "DeleteFeed"));
        serviceClient.sendReceive(request);
    }

    public void deleteFeed() throws AxisFault {
        if (feedEpr != null) {
            deleteFeed(feedEpr);
        } else {
            throw new AxisFault(
                    "No feed epr alreday stored, you must have create a feed using same AtomEventingClient Object");
        }
    }

    public OMElement fetchFeed(String url) throws SavanException {
        // Create an instance of HttpClient.
        HttpClient client = new HttpClient();

        // Create a method instance.
        GetMethod method = new GetMethod(url);

        try {
            // Execute the method.
            int statusCode = client.executeMethod(method);

            if (statusCode != HttpStatus.SC_OK) {
                throw new SavanException("Method failed: " + method.getStatusLine());
            }

            // Read the response body.
            byte[] responseBody = method.getResponseBody();

            StAXOMBuilder builder = new StAXOMBuilder(new ByteArrayInputStream(
                    responseBody));
            return builder.getDocumentElement();
        } catch (IOException e) {
            throw new SavanException(e);
        } catch (XMLStreamException e) {
            throw new SavanException(e);
        } finally {
            // Release the connection.
            method.releaseConnection();
        }
    }

    public void publishWithREST(String serviceurl, final OMElement content, String topic)
            throws SavanException {
        // Create an instance of HttpClient.
        HttpClient client = new HttpClient();

        StringBuffer queryUrl = new StringBuffer(serviceurl);

        if (!serviceurl.endsWith("/")) {
            queryUrl.append("/");
        }
        queryUrl.append("publish");
        if (topic != null) {
            queryUrl.append("?").append(EventingConstants.ElementNames.Topic).append("=")
                    .append(topic);
        }
        PostMethod method = new PostMethod(queryUrl.toString());
        // Request content will be retrieved directly
        // from the input stream
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            content.serialize(out);
            out.flush();
            final byte[] data = out.toByteArray();

            RequestEntity entity = new RequestEntity() {

                public void writeRequest(OutputStream outstream)
                        throws IOException {
                    outstream.write(data);
                }

                public boolean isRepeatable() {
                    return false;
                }

                public String getContentType() {
                    return "text/xml";
                }

                public long getContentLength() {
                    return data.length;
                }

            };
            method.setRequestEntity(entity);

            // Execute the method.
            int statusCode = client.executeMethod(method);

            if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_ACCEPTED) {
                throw new SavanException("Method failed: " + method.getStatusLine());
            }

        } catch (IOException e) {
            throw new SavanException(e);
        } catch (XMLStreamException e) {
            throw new SavanException(e);
        } finally {
            // Release the connection.
            method.releaseConnection();
        }
    }

    public void publishWithSOAP(String serviceurl, final OMElement content, String topic)
            throws SavanException {
        try {
            Options options = serviceClient.getOptions();
            EndpointReference to = new EndpointReference(serviceurl);
            if (topic != null) {
                to.addReferenceParameter(new QName(EventingConstants.EXTENDED_EVENTING_NAMESPACE,
                                                   EventingConstants.ElementNames.Topic), topic);
            }
            options.setAction(EventingConstants.Actions.Publish);
            serviceClient.fireAndForget(content);
        } catch (AxisFault e) {
            throw new SavanException(e);
        }
    }


}
