/*
 * Copyright 2002-2007 Network Engine for Objects in Lund AB [neotechnology.com]
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package unit.neo.transaction;

import java.util.ArrayList;

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

class FakeXAResource implements XAResource
{
	private String name = null;
	private int transactionTimeout = 0;
	private ArrayList<MethodCall> methodCalls = 
		new ArrayList<MethodCall>();
	
	FakeXAResource( String name )
	{
		this.name = name;
	}
	
	public String getName()
	{
		return name;
	}
	
	public String toString()
	{
		return name;
	}
	
	synchronized MethodCall[] getAndRemoveMethodCalls()
	{
		if ( methodCalls.size() > 0 )
		{
			MethodCall methodCallArray[] = 
				new MethodCall[ methodCalls.size() ];
			methodCallArray = methodCalls.toArray( methodCallArray );
			methodCalls = new ArrayList<MethodCall>();
			return methodCallArray;
		}
		return new MethodCall[0];
	}
	
	private synchronized void addMethodCall( MethodCall methodCall )
	{
		methodCalls.add( methodCall );
	}
	
	public void commit( Xid xid, boolean onePhase )
	{
		addMethodCall( new MethodCall( "commit", 
			new Object[] { xid, new Boolean( onePhase ) },
			new String[] {	"javax.transaction.xa.Xid",
							"java.lang.Boolean" } ) );
	}
	
	public void end( Xid xid, int flags )
	{
		addMethodCall( new MethodCall( "end", 
			new Object[] { xid, new Integer( flags ) },
			new String[] {	"javax.transaction.xa.Xid",
							"java.lang.Integer" } ) );
	}
	
	public void forget( Xid xid )
	{
		addMethodCall( new MethodCall( "forget", 
			new Object[] { xid },
			new String[] {	"javax.transaction.xa.Xid" } ) );
	}
	
	public int getTransactionTimeout()
	{
		return transactionTimeout;
	}
	
	public boolean setTransactionTimeout( int timeout )
	{
		transactionTimeout = timeout;
		return true;
	}
	
	public boolean isSameRM( XAResource xares )
	{
		if ( xares instanceof FakeXAResource )
		{
			if ( this.name.equals( ((FakeXAResource) xares).getName() ) )
			{
				return true;
			}
		}
		return false;
	}
	
	public int prepare( Xid xid )
	{
		addMethodCall( new MethodCall( "prepare", 
			new Object[] { xid },
			new String[] {	"javax.transaction.xa.Xid" } ) );
		return XAResource.XA_OK;
	}
	
	public Xid[] recover( int flag )
	{
		addMethodCall( new MethodCall( "recover", 
			new Object[] { new Integer( flag ) },
			new String[] {	"java.lang.Integer" } ) );
		return new Xid[0];
	}
	
	public void rollback( Xid xid )
	{
		addMethodCall( new MethodCall( "rollback", 
			new Object[] { xid },
			new String[] { "javax.transaction.xa.Xid" } ) );
	}
	
	public void start( Xid xid, int flags )
	{
		addMethodCall( new MethodCall( "start", 
			new Object[] { xid, new Integer( flags ) },
			new String[] {	"javax.transaction.xa.Xid",
							"java.lang.Integer" } ) );
	}
}