/*
 * Copyright 2004-2014 the Seasar Foundation and the Others.
 *
 * 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.seasar.extension.jta.xa;

import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * @author higa
 *
 */
public class DefaultXAResourceTest {

    /** target */
    private DefaultXAResource xaRes = null;

    /**
     * setUp
     */
    @Before
    public void setUp() {
        this.xaRes = new DefaultXAResource();
    }

    /**
     * testStart
     * @throws Exception Exception
     */
    @Test
    public void testStart() throws Exception {
        final Xid xid = new XidImpl();
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        Assert.assertEquals("1", xid, this.xaRes.getCurrentXid());
        Assert.assertEquals("2", XAResourceStatus.RS_ACTIVE.value(), this.xaRes.getStatus());
        try {
            this.xaRes.start(xid, XAResource.TMNOFLAGS);
            Assert.fail("3");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }

        final DefaultXAResource xaRes2 = new DefaultXAResource();
        final Xid xid2 = new XidImpl();
        xaRes2.start(xid2, XAResource.TMNOFLAGS);
        xaRes2.end(xid2, XAResource.TMSUSPEND);
        xaRes2.start(xid2, XAResource.TMRESUME);
        Assert.assertEquals("4", xid2, xaRes2.getCurrentXid());
        Assert.assertEquals("5", XAResourceStatus.RS_ACTIVE.value(), xaRes2.getStatus());
        try {
            xaRes2.start(xid, XAResource.TMRESUME);
            Assert.fail("6");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }

        final DefaultXAResource xaRes3 = new DefaultXAResource();
        try {
            xaRes3.start(xid, XAResource.TMJOIN);
            Assert.fail("7");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }

        final DefaultXAResource xaRes4 = new DefaultXAResource();
        try {
            xaRes4.start(xid, -1);
            Assert.fail("8");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * testEnd
     * @throws Exception Exception
     */
    @Test
    public void testEnd() throws Exception {
        final Xid xid = new XidImpl();
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMSUSPEND);
        Assert.assertEquals("1", XAResourceStatus.RS_SUSPENDED.value(), this.xaRes.getStatus());

        this.xaRes.forget(xid);
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMFAIL);
        Assert.assertEquals("2", XAResourceStatus.RS_FAIL.value(), this.xaRes.getStatus());

        this.xaRes.forget(xid);
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMSUCCESS);
        Assert.assertEquals("3", XAResourceStatus.RS_SUCCESS.value(), this.xaRes.getStatus());

        this.xaRes.forget(xid);
        try {
            this.xaRes.end(xid, XAResource.TMSUCCESS);
            Assert.fail("4");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }

        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        try {
            this.xaRes.end(xid, -1);
            Assert.fail("5");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }

        final Xid xid2 = new XidImpl();
        try {
            this.xaRes.end(xid2, XAResource.TMSUCCESS);
            Assert.fail("6");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * testPrepare
     * @throws Exception Exception
     */
    @Test
    public void testPrepare() throws Exception {
        final Xid xid = new XidImpl();
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMSUCCESS);
        Assert.assertEquals("1", XAResource.XA_OK, this.xaRes.prepare(xid));
        Assert.assertEquals("2", XAResourceStatus.RS_PREPARED.value(), this.xaRes.getStatus());

        this.xaRes.forget(xid);
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMFAIL);
        try {
            this.xaRes.prepare(xid);
            Assert.fail("4");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }

        this.xaRes.forget(xid);
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMSUCCESS);
        try {
            this.xaRes.prepare(new XidImpl());
            Assert.fail("5");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * testCommit1
     * @throws Exception Exception
     */
    @Test
    public void testCommit1() throws Exception {
        final Xid xid = new XidImpl();
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMSUCCESS);
        this.xaRes.commit(xid, true);
        Assert.assertEquals("1", XAResourceStatus.RS_NONE.value(), this.xaRes.getStatus());
        Assert.assertNull("2", this.xaRes.getCurrentXid());

        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMSUCCESS);
        this.xaRes.prepare(xid);
        this.xaRes.commit(xid, false);
        Assert.assertEquals("3", XAResourceStatus.RS_NONE.value(), this.xaRes.getStatus());
        Assert.assertNull("4", this.xaRes.getCurrentXid());
    }

    /**
     * testCommit2
     * @throws Exception Exception
     */
    @Test
    public void testCommit2() throws Exception {
        final Xid xid = new XidImpl();
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMFAIL);
        try {
            this.xaRes.commit(xid, true);
            Assert.fail("5");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }

        this.xaRes.forget(xid);
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMSUCCESS);
        try {
            this.xaRes.commit(xid, false);
            Assert.fail("6");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }

        this.xaRes.forget(xid);
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMSUCCESS);
        try {
            this.xaRes.commit(new XidImpl(), true);
            Assert.fail("7");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * testRollback
     * @throws Exception Exception
     */
    @Test
    public void testRollback() throws Exception {
        final Xid xid = new XidImpl();
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMFAIL);
        this.xaRes.rollback(xid);
        Assert.assertEquals("1", XAResourceStatus.RS_NONE.value(), this.xaRes.getStatus());
        Assert.assertNull("2", this.xaRes.getCurrentXid());

        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMSUCCESS);
        this.xaRes.prepare(xid);
        this.xaRes.rollback(xid);
        Assert.assertEquals("3", XAResourceStatus.RS_NONE.value(), this.xaRes.getStatus());
        Assert.assertNull("4", this.xaRes.getCurrentXid());

        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        try {
            this.xaRes.rollback(xid);
            Assert.fail("5");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }

        this.xaRes.forget(xid);
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.end(xid, XAResource.TMFAIL);
        try {
            this.xaRes.rollback(new XidImpl());
            Assert.fail("6");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * testForget
     * @throws Exception Exception
     */
    @Test
    public void testForget() throws Exception {
        final Xid xid = new XidImpl();
        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        this.xaRes.forget(xid);
        Assert.assertNull("1", this.xaRes.getCurrentXid());
        Assert.assertEquals("2", XAResourceStatus.RS_NONE.value(), this.xaRes.getStatus());

        this.xaRes.start(xid, XAResource.TMNOFLAGS);
        try {
            this.xaRes.forget(new XidImpl());
            Assert.fail("3");
        } catch (final XAException ex) {
            ex.printStackTrace();
        }
    }
}
