/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.axis2.savan;

import junit.framework.TestCase;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.databinding.utils.ConverterUtil;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.savan.SavanConstants;
import org.apache.savan.SavanMessageContext;
import org.apache.savan.configuration.ConfigurationManager;
import org.apache.savan.configuration.Protocol;
import org.apache.savan.eventing.EventingConstants;
import org.apache.savan.eventing.EventingSubscriptionProcessor;
import org.apache.savan.eventing.subscribers.EventingSubscriber;
import org.apache.savan.storage.DefaultSubscriberStore;
import org.apache.savan.storage.SubscriberStore;
import org.apache.savan.subscription.ExpirationBean;
import org.apache.savan.util.CommonUtil;

import javax.xml.namespace.QName;
import java.io.File;
import java.io.IOException;
import java.util.Date;

public class EventingSubscripitonProcessorTest extends TestCase {

    private final String TEST_SAVAN_CONFIG = "savan-config-test.xml";
    private final String EVENTING_PROTOCOL_NAME = "eventing";

    public void testSubscriberExtraction() throws Exception {
        SavanMessageContext smc = getSubscriptionMessage();

//		Protocol protocol = new Protocol ();
//		protocol.setName("eventing");
//		protocol.setUtilFactory(new EventingUtilFactory ());
//		protocol.setDefaultSubscriber("org.apache.savan.eventing.subscribers.EventingLeafSubscriber");

        SubscriberStore store = new DefaultSubscriberStore();

//		smc.setProtocol(protocol);

        smc.setSubscriberStore(store);

        EventingSubscriptionProcessor esp = new EventingSubscriptionProcessor();
        EventingSubscriber eventingSubscriber =
                (EventingSubscriber)esp.getSubscriberFromMessage(smc);
        assertNotNull(eventingSubscriber);

        assertNotNull(eventingSubscriber.getDelivery());
        assertNotNull(eventingSubscriber.getDelivery().getDeliveryEPR());
        assertNotNull(eventingSubscriber.getFilter());
        assertNotNull(eventingSubscriber.getEndToEPr());
        assertNotNull(eventingSubscriber.getId());
        assertNotNull(eventingSubscriber.getSubscriptionEndingTime());

        assertEquals(eventingSubscriber.getDelivery().getDeliveryMode(),
                     EventingConstants.DEFAULT_DELIVERY_MODE);

        assertEquals(eventingSubscriber.getDelivery().getDeliveryEPR().getAddress(),
                     "http://www.other.example.com/OnStormWarning");
        assertEquals(eventingSubscriber.getEndToEPr().getAddress(),
                     "http://www.example.com/MyEventSink");
        Date date = ConverterUtil.convertToDateTime("2004-06-26T21:07:00.000-08:00").getTime();
        assertEquals(eventingSubscriber.getSubscriptionEndingTime(), date);
    }

    public void testExpirationBeanExtraction() throws Exception {
        SavanMessageContext smc = getRenewMessage();
        EventingSubscriptionProcessor esp = new EventingSubscriptionProcessor();
        ExpirationBean expirationBean = esp.getExpirationBean(smc);

        assertNotNull(expirationBean);
        assertNotNull(expirationBean.getSubscriberID());

        Date date = ConverterUtil.convertToDateTime("2004-06-26T21:07:00.000-08:00").getTime();
        assertEquals(expirationBean.getDateValue(), date);
    }

    private SavanMessageContext getSubscriptionMessage() throws IOException {
        File baseDir = new File("");
        String testRource = baseDir.getAbsolutePath() + File.separator + "src" + File.separator +
                            "test" + File.separator + "resources";

        SOAPEnvelope envelope = CommonUtil.getTestEnvelopeFromFile(testRource,
                                                                   "eventing-subscription.xml",
                                                                   OMAbstractFactory.getSOAP12Factory());

        AxisConfiguration axisConfiguration = new AxisConfiguration();
        ConfigurationContext configurationContext = new ConfigurationContext(axisConfiguration);

        MessageContext mc = new MessageContext();
        SavanMessageContext smc = new SavanMessageContext(mc);
        mc.setEnvelope(envelope);

        mc.setConfigurationContext(configurationContext);

        Options options = new Options();
        options.setTo(new EndpointReference("http://DummyToAddress/"));

        EndpointReference replyToEPR = new EndpointReference("http://DummyReplyToAddress/");
        replyToEPR.addReferenceParameter(new QName("RefParam1"), "RefParamVal1");
        options.setTo(replyToEPR);

        //adding a dummy AxisService to avoid NullPointer Exceptions.
        mc.setAxisService(new AxisService("DummyService"));

        options.setAction("urn:uuid:DummyAction");

        String savan_concig_file = testRource + File.separator + TEST_SAVAN_CONFIG;
        File file = new File(savan_concig_file);
        if (!file.exists())
            throw new IOException(TEST_SAVAN_CONFIG + " file is not available in test-resources.");

        ConfigurationManager configurationManager = new ConfigurationManager();
        configurationManager.configure(file);

        configurationContext
                .setProperty(SavanConstants.CONFIGURATION_MANAGER, configurationManager);

        Protocol protocol = configurationManager.getProtocol(EVENTING_PROTOCOL_NAME);
        smc.setProtocol(protocol);

        return smc;
    }

    private SavanMessageContext getRenewMessage() throws IOException {
        File baseDir = new File("");
        String testRource = baseDir.getAbsolutePath() + File.separator + "src" + File.separator +
                            "test" + File.separator + "resources";

        SOAPEnvelope envelope = CommonUtil.getTestEnvelopeFromFile(testRource,
                                                                   "eventing-renew-datetime.xml",
                                                                   OMAbstractFactory.getSOAP12Factory());

        MessageContext mc = new MessageContext();
        SavanMessageContext smc = new SavanMessageContext(mc);
        mc.setEnvelope(envelope);

        Options options = new Options();
        options.setTo(new EndpointReference("http://DummyToAddress/"));

        EndpointReference replyToEPR = new EndpointReference("http://DummyReplyToAddress/");
        replyToEPR.addReferenceParameter(new QName("RefParam1"), "RefParamVal1");
        options.setTo(replyToEPR);

        options.setAction("urn:uuid:DummyAction");

        return smc;
    }
}
