/*
 * 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.aries.transaction.itests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.ops4j.pax.exam.CoreOptions.composite;
import static org.ops4j.pax.exam.CoreOptions.frameworkProperty;
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.systemProperty;
import static org.ops4j.pax.exam.CoreOptions.vmOption;
import static org.ops4j.pax.exam.CoreOptions.when;

import java.sql.SQLException;

import javax.inject.Inject;
import javax.transaction.RollbackException;
import javax.transaction.UserTransaction;

import org.apache.aries.transaction.test.Counter;
import org.apache.aries.transaction.test.TestBean;
import org.junit.Assert;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.CoreOptions;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.options.extra.CleanCachesOption;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;

@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public abstract class AbstractIntegrationTest {
    @Inject
    BundleContext bundleContext;
    
    @Inject
    UserTransaction tran;
    
    @Inject
    Counter counter;

    protected boolean clientTransaction = true;

    public Option baseOptions() {
        String localRepo = System.getProperty("maven.repo.local");
        if (localRepo == null) {
            localRepo = System.getProperty("org.ops4j.pax.url.mvn.localRepository");
        }
        return composite(
                junitBundles(),
                new CleanCachesOption(true), // change to 'false' if investigation is needed
                // this is how you set the default log level when using pax
                // logging (logProfile)
                systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("INFO"),
                // this option helps with debugging
                //vmOption("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5006"),
                when(localRepo != null).useOptions(vmOption("-Dorg.ops4j.pax.url.mvn.localRepository=" + localRepo))
         );
    }

    @Configuration
    public Option[] configuration() {
        return new Option[] {
                baseOptions(),
                frameworkProperty("org.osgi.framework.system.packages")
                    .value("javax.accessibility,javax.activation,javax.activity,javax.annotation,javax.annotation.processing,javax.crypto,javax.crypto.interfaces,javax.crypto.spec,javax.imageio,javax.imageio.event,javax.imageio.metadata,javax.imageio.plugins.bmp,javax.imageio.plugins.jpeg,javax.imageio.spi,javax.imageio.stream,javax.jws,javax.jws.soap,javax.lang.model,javax.lang.model.element,javax.lang.model.type,javax.lang.model.util,javax.management,javax.management.loading,javax.management.modelmbean,javax.management.monitor,javax.management.openmbean,javax.management.relation,javax.management.remote,javax.management.remote.rmi,javax.management.timer,javax.naming,javax.naming.directory,javax.naming.event,javax.naming.ldap,javax.naming.spi,javax.net,javax.net.ssl,javax.print,javax.print.attribute,javax.print.attribute.standard,javax.print.event,javax.rmi,javax.rmi.CORBA,javax.rmi.ssl,javax.script,javax.security.auth,javax.security.auth.callback,javax.security.auth.kerberos,javax.security.auth.login,javax.security.auth.spi,javax.security.auth.x500,javax.security.cert,javax.security.sasl,javax.sound.midi,javax.sound.midi.spi,javax.sound.sampled,javax.sound.sampled.spi,javax.sql,javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi,javax.swing,javax.swing.border,javax.swing.colorchooser,javax.swing.event,javax.swing.filechooser,javax.swing.plaf,javax.swing.plaf.basic,javax.swing.plaf.metal,javax.swing.plaf.multi,javax.swing.plaf.synth,javax.swing.table,javax.swing.text,javax.swing.text.html,javax.swing.text.html.parser,javax.swing.text.rtf,javax.swing.tree,javax.swing.undo,javax.tools,javax.xml,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.bind.util,javax.xml.crypto,javax.xml.crypto.dom,javax.xml.crypto.dsig,javax.xml.crypto.dsig.dom,javax.xml.crypto.dsig.keyinfo,javax.xml.crypto.dsig.spec,javax.xml.datatype,javax.xml.namespace,javax.xml.parsers,javax.xml.soap,javax.xml.stream,javax.xml.stream.events,javax.xml.stream.util,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stax,javax.xml.transform.stream,javax.xml.validation,javax.xml.ws,javax.xml.ws.handler,javax.xml.ws.handler.soap,javax.xml.ws.http,javax.xml.ws.soap,javax.xml.ws.spi,javax.xml.xpath,org.ietf.jgss,org.omg.CORBA,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA.TypeCodePackage,org.omg.CORBA.portable,org.omg.CORBA_2_3,org.omg.CORBA_2_3.portable,org.omg.CosNaming,org.omg.CosNaming.NamingContextExtPackage,org.omg.CosNaming.NamingContextPackage,org.omg.Dynamic,org.omg.DynamicAny,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage,org.omg.IOP,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage,org.omg.Messaging,org.omg.PortableInterceptor,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.PortableServer,org.omg.PortableServer.CurrentPackage,org.omg.PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.ServantLocatorPackage,org.omg.PortableServer.portable,org.omg.SendingContext,org.omg.stub.java.rmi,org.w3c.dom,org.w3c.dom.bootstrap,org.w3c.dom.css,org.w3c.dom.events,org.w3c.dom.html,org.w3c.dom.ls,org.w3c.dom.ranges,org.w3c.dom.stylesheets,org.w3c.dom.traversal,org.w3c.dom.views,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers"),
                systemProperty("org.apache.aries.proxy.weaving.enabled").value("none"),
                systemProperty("pax.exam.osgi.unresolved.fail").value("true"),

                // Bundles
                mavenBundle("org.ops4j.pax.logging", "pax-logging-api").versionAsInProject(),
                mavenBundle("org.ops4j.pax.logging", "pax-logging-service").versionAsInProject(),
                mavenBundle("org.apache.felix", "org.apache.felix.configadmin").versionAsInProject(),
                mavenBundle("org.apache.felix", "org.apache.felix.coordinator").versionAsInProject(),
                
                mavenBundle("org.apache.geronimo.specs", "geronimo-j2ee-connector_1.6_spec").versionAsInProject(),
                mavenBundle("org.apache.geronimo.specs", "geronimo-validation_1.0_spec").versionAsInProject(),
                mavenBundle("org.apache.geronimo.components", "geronimo-connector").versionAsInProject(),

                mavenBundle("org.apache.derby", "derby").versionAsInProject(),
                mavenBundle("org.apache.aries", "org.apache.aries.util").versionAsInProject(),
                mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.api").versionAsInProject(),
                mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.core").versionAsInProject(),
                mavenBundle("org.apache.aries.proxy", "org.apache.aries.proxy.api").versionAsInProject(),
                mavenBundle("org.apache.aries.proxy", "org.apache.aries.proxy.impl").versionAsInProject(),
                jta12Bundles(),
                mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.manager").versionAsInProject(),
                mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.blueprint").versionAsInProject(),
                mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.jdbc").versionAsInProject(),
                mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.testbundle").versionAsInProject(),
                mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.testds").versionAsInProject(),

                //debug(),
                //new TimeoutOption( 0 ),
        };
    }

    protected Option debug() {
        return vmOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005");
    }

    private Option jta12Bundles() {
            return CoreOptions.composite(
                mavenBundle("javax.interceptor", "javax.interceptor-api").versionAsInProject(),
                mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.javax-inject").versionAsInProject(),
                mavenBundle("javax.el", "javax.el-api").versionAsInProject(),
                mavenBundle("javax.enterprise", "cdi-api").versionAsInProject(),
                mavenBundle("javax.transaction", "javax.transaction-api").versionAsInProject()
            );
    }
    
    /**
     * Helps to diagnose bundles that are not resolved as it will throw a detailed exception
     * 
     * @throws BundleException
     */
    public void resolveBundles() throws BundleException {
        System.out.println("Checking for bundles");
        Bundle[] bundles = bundleContext.getBundles();
        for (Bundle bundle : bundles) {
            if (bundle.getState() == Bundle.INSTALLED) {
                System.out.println("Found non resolved bundle " + bundle.getBundleId() + ":"
                    + bundle.getSymbolicName() + ":" + bundle.getVersion());
                bundle.start();
            }
        }
    }

    // Test with client transaction and runtime exception - the user transaction is rolled back
    protected void assertInsertWithRuntimeExceptionRolledBack() throws Exception {
        TestBean bean = getBean();
        int initialRows = counter.countRows();

        if (clientTransaction) {
            tran.begin();
        }
        bean.insertRow("testWithClientTranAndWithRuntimeException", 1, null);
        try {
            bean.insertRow("testWithClientTranAndWithRuntimeException", 2, new RuntimeException("Dummy exception"));
        } catch (RuntimeException e) {
            Assert.assertEquals("Dummy exception", e.getMessage());
        }
        if (clientTransaction) {
            try {
                tran.commit();
                fail("RollbackException not thrown");
            } catch (RollbackException e) {
                // Ignore expected
            }
        }

        int finalRows = counter.countRows();
        // In case of client transaction both are rolled back
        // In case of container transaction only second insert is rolled back
        assertEquals("Added rows", clientTransaction ? 0 : 1, finalRows - initialRows);
    }

    protected void assertInsertWithAppExceptionCommitted() throws Exception {
        TestBean bean = getBean();
        int initialRows = counter.countRows();
        if (clientTransaction) {
            tran.begin();
        }
        bean.insertRow("testWithClientTranAndWithAppException", 1, null);
        try {
            bean.insertRow("testWithClientTranAndWithAppException", 2, new SQLException("Dummy exception"));
        } catch (SQLException e) {
            Assert.assertEquals("Dummy exception", e.getMessage());
        }
        if (clientTransaction) {
            tran.commit();
        }

        int finalRows = counter.countRows();
        assertEquals("Added rows", 2, finalRows - initialRows);
    }

    protected void assertInsertSuccesful() throws Exception {
        TestBean bean = getBean();
        int initialRows = counter.countRows();

        if (clientTransaction ) {
            tran.begin();
        }
        bean.insertRow("testWithClientTran", 1, null);
        if (clientTransaction ) {
            tran.commit();
        }
        int finalRows = counter.countRows();
        assertEquals("Added rows", 1, finalRows - initialRows);
    }

    protected void assertInsertFails() throws Exception {
        TestBean bean = getBean();
        int initialRows = counter.countRows();
        if (clientTransaction ) {
            tran.begin();
        }
        try {
            bean.insertRow("testWithClientTran", 1, null);
            fail("IllegalStateException not thrown");
        } catch (IllegalStateException e) {
            // Ignore Expected
        }
        if (clientTransaction ) {
            tran.commit();
        }
        int finalRows = counter.countRows();
        assertEquals("Added rows", 0, finalRows - initialRows);
    }
    
    // Test without client transaction - the insert fails because the bean delegates to another
    // bean with a transaction strategy of Mandatory, and no transaction is available
    protected void assertDelegateInsertFails() throws Exception {
        TestBean bean = getBean();
        int initialRows = counter.countRows();

        if (clientTransaction ) {
            tran.begin();
        }
        try {
            bean.delegateInsertRow("testWithoutClientTran", 1);
            fail("IllegalStateException not thrown");
        } catch (IllegalStateException e) {
            // Ignore expected
        }
        if (clientTransaction ) {
            tran.commit();
        }
        int finalRows = counter.countRows();
        assertEquals("Added rows", 0, finalRows - initialRows);
    }

    // Test without client transaction - an exception is thrown because a transaction is mandatory
    protected void assertMandatoryTransaction() throws SQLException {
          try {
              getBean().insertRow("testWithoutClientTran", 1, null);
              fail("IllegalStateException not thrown");
          } catch (IllegalStateException e) {
              // Ignore expected
          }
    }
    
    protected abstract TestBean getBean();

    protected void assertDelegateInsert() throws Exception {
        TestBean bean = getBean();
        int initialRows = counter.countRows();
    
        tran.begin();
        bean.delegateInsertRow("testWithClientTran", 1);
        tran.commit();
    
        int finalRows = counter.countRows();
        assertEquals("Added rows", 1, finalRows - initialRows);
    }
}