/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.camel.component.cxf;

import java.io.ByteArrayOutputStream;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Processor;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.spi.Synchronization;
import org.apache.camel.test.spring.CamelSpringTestSupport;
import org.apache.hello_world_soap_http.Greeter;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.AbstractXmlApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Tests a cxf routing scenario from an oneway cxf EP to a file EP to not forward the old input
 * back to the oneway cxf EP.
 */
public class CxfOneWayRouteTest extends CamelSpringTestSupport {
    private static final QName SERVICE_NAME = new QName("http://apache.org/hello_world_soap_http", "SOAPService");
    private static final QName PORT_NAME = new QName("http://apache.org/hello_world_soap_http", "SoapPort");
    private static final String ROUTER_ADDRESS = "http://localhost:" + CXFTestSupport.getPort1() + "/CxfOneWayRouteTest/router";

    private static Exception bindingException;
    private static boolean bindingDone;
    private static boolean onCompeletedCalled;

    @Before
    public void setup() {
        bindingException = null;
        bindingDone = false;
        onCompeletedCalled = false;
    }
    
    @Override
    protected AbstractXmlApplicationContext createApplicationContext() {
        // we can put the http conduit configuration here
        return new ClassPathXmlApplicationContext("org/apache/camel/component/cxf/CxfOneWayRouteBeans.xml");
    }
    
    protected Greeter getCXFClient() throws Exception {
        Service service = Service.create(SERVICE_NAME);
        service.addPort(PORT_NAME, "http://schemas.xmlsoap.org/soap/", ROUTER_ADDRESS);
        Greeter greeter = service.getPort(PORT_NAME, Greeter.class);
        return greeter;
    }

    @Test
    public void testInvokingOneWayServiceFromCXFClient() throws Exception {
        MockEndpoint mock = getMockEndpoint("mock:result");
        mock.expectedMessageCount(1);
        mock.expectedFileExists("target/camel-file/cxf-oneway-route");
        
        Greeter client = getCXFClient();
        client.greetMeOneWay("lemac");

        // may need to wait until the oneway call completes 
        long waitUntil = System.currentTimeMillis() + 10000;
        while (!bindingDone && System.currentTimeMillis() < waitUntil) {
            Thread.sleep(1000);
        }

        assertMockEndpointsSatisfied();
        assertTrue("UnitOfWork done should be called", onCompeletedCalled);
        assertNull("exception occured: " + bindingException, bindingException);
    }
    
    public static class TestProcessor implements Processor {
        static final byte[] MAGIC = {(byte)0xca, 0x3e, 0x1e};

        @Override
        public void process(Exchange exchange) throws Exception {
            // just check the MEP here
            assertEquals("Don't get the right MEP", ExchangePattern.InOnly, exchange.getPattern());
            // adding some binary segment
            String msg = exchange.getIn().getBody(String.class);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bos.write(MAGIC);
            bos.write(msg.getBytes());
            exchange.getIn().setBody(bos.toByteArray());
            // add compliation
            exchange.getUnitOfWork().addSynchronization(new Synchronization() {
                @Override
                public void onComplete(Exchange exchange) {
                    onCompeletedCalled = true;
                }

                @Override
                public void onFailure(Exchange exchange) {
                    // do nothing here
                }
            });
        }
    }
    
    public static class TestCxfBinding extends DefaultCxfBinding {

        @Override
        public void populateCxfResponseFromExchange(Exchange camelExchange, org.apache.cxf.message.Exchange cxfExchange) {
            try {
                super.populateCxfResponseFromExchange(camelExchange, cxfExchange);
            } catch (RuntimeException e) {
                bindingException = e;
                throw e;
            } finally {
                bindingDone = true;
            }
        }
        
    }
}
