/*
 * 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.axis2.saaj;

import java.lang.reflect.Method;

import org.junit.internal.runners.InitializationError;
import org.junit.internal.runners.JUnit4ClassRunner;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;

/**
 * Special JUnit test runner that allows test cases to be validated against
 * Sun's SAAJ implementation.
 * If a test method is annotated with {@link Validated} (in addition to {@link org.junit.Test},
 * then this runner will execute the test twice: once with Sun's SAAJ implementation and
 * once with Axis2's. This is a convenient way to validate test cases, i.e. to make sure that
 * the test cases make correct assertions about SAAJ behavior. Of course this makes the implicit
 * assumption that Sun's implementation is bug free, which is not necessarily the case...
 */
public class SAAJTestRunner extends JUnit4ClassRunner {
    private static class MultiRunListener extends RunListener {
        private final RunNotifier notifier;
        private boolean firstRun = true;
        private int runs;
        private String failureMessage;
        
        public MultiRunListener(RunNotifier notifier, int runs) {
            this.notifier = notifier;
            this.runs = runs;
        }

        @Override
        public void testStarted(Description description) throws Exception {
            runs--;
            if (firstRun) {
                notifier.fireTestStarted(description);
                firstRun = false;
            }
        }
        
        @Override
        public void testFailure(Failure failure) throws Exception {
            if (failureMessage != null) {
                failure = new Failure(failure.getDescription(), new Error(failureMessage,
                        failure.getException()));
            }
            notifier.fireTestFailure(failure);
            runs = 0;
        }

        @Override
        public void testIgnored(Description description) throws Exception {
            notifier.fireTestIgnored(description);
            runs = 0;
        }

        @Override
        public void testFinished(Description description) throws Exception {
            if (runs == 0) {
                notifier.fireTestFinished(description);
            }
        }
        
        public void setFailureMessage(String failureMessage) {
            this.failureMessage = failureMessage;
        }

        public boolean isShouldContinue() {
            return runs > 0;
        }
    }
    
    public SAAJTestRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected void invokeTestMethod(Method method, RunNotifier notifier) {
        boolean validate = method.getAnnotation(Validated.class) != null;
        RunNotifier multiRunNotifier = new RunNotifier();
        MultiRunListener multiRunListener = new MultiRunListener(notifier, validate ? 2 : 1);
        multiRunNotifier.addListener(multiRunListener);
        if (validate) {
            multiRunListener.setFailureMessage(
                    "Invalid test case; execution failed with SAAJ reference implementation");

            System.setProperty("javax.xml.soap.MessageFactory",
            		"com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl");
            System.setProperty("javax.xml.soap.SOAPFactory",
            		"com.sun.xml.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl");
            System.setProperty("javax.xml.soap.SOAPConnectionFactory",
            		"com.sun.xml.messaging.saaj.client.p2p.HttpSOAPConnectionFactory");
            System.setProperty("javax.xml.soap.MetaFactory",
            		"com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl");

            super.invokeTestMethod(method, multiRunNotifier);
        }
        if (multiRunListener.isShouldContinue()) {
            multiRunListener.setFailureMessage(null);
            System.setProperty("javax.xml.soap.MessageFactory",
                    "org.apache.axis2.saaj.MessageFactoryImpl");
            System.setProperty("javax.xml.soap.SOAPFactory",
                    "org.apache.axis2.saaj.SOAPFactoryImpl");
            System.setProperty("javax.xml.soap.SOAPConnectionFactory",
                    "org.apache.axis2.saaj.SOAPConnectionFactoryImpl");
            System.setProperty("javax.xml.soap.MetaFactory",
                    "org.apache.axis2.saaj.SAAJMetaFactoryImpl");
            super.invokeTestMethod(method, multiRunNotifier);
        }
    }
}
