package org.simplejta.tests.xa;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;

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

import org.apache.derby.jdbc.ClientXADataSource;

public class RecoveryError {

    public static void main(String[] args) {
        
        // Create a XADataSource instance
        ClientXADataSource ds1=new ClientXADataSource();    
        ds1.setDatabaseName("tca");   
        ds1.setServerName("localhost");        // host with listening network server.
        ds1.setPortNumber(1527);               // port of listening network server.
        ds1.setUser("app");		      // Assign the user ID
        ds1.setPassword("app");	      // Assign the password
        
		try {
            // Get a XA connection to the underlying data source
            XAConnection pc1 = ds1.getXAConnection();

            // Get the XA Resource
            XAResource oxar1 = pc1.getXAResource();

            // Create the Xid
            Xid xid1 = createXid(1);

            // Start the XA transaction
            oxar1.start(xid1, XAResource.TMNOFLAGS);

            // Get a Logical Connection
            Connection conn = pc1.getConnection();

            Statement stmt = conn.createStatement();
            int cnt = stmt.executeUpdate("INSERT INTO dept VALUES (50, 'BSD', 'LONDON')");
            System.out.println("No of rows inserted " + cnt);
            stmt.close();
            
            conn.close();

            // Get a Logical Connection
            conn = pc1.getConnection();

            stmt = conn.createStatement();
            cnt = stmt.executeUpdate("INSERT INTO dept VALUES (51, 'BSD', 'LONDON')");
            System.out.println("No of rows inserted " + cnt);
            stmt.close();
            
            conn.close();
            
            // END the branche
            oxar1.end(xid1, XAResource.TMSUCCESS);
		} catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (XAException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
		
    }
    
    static int next = 1;
    
    static Xid createXid(int bids) throws XAException {
        byte[] gid = new byte[1];
        gid[0] = (byte) next++;
        byte[] bid = new byte[1];
        bid[0] = (byte) bids;
        byte[] gtrid = new byte[64];
        byte[] bqual = new byte[64];
        System.arraycopy(gid, 0, gtrid, 0, 1);
        System.arraycopy(bid, 0, bqual, 0, 1);
        Xid xid = new XidImpl(0x1234, gtrid, bqual);
        return xid;
    }
}

class XidImpl implements Xid {

	int formatId;

	byte[] gtrid;

	byte[] bqual;

	public XidImpl(int formatId, byte[] gtrid, byte[] bqual) {
		this.formatId = formatId;
		this.gtrid = gtrid;
		this.bqual = bqual;
	}

	public byte[] getBranchQualifier() {
		return bqual;
	}

	public int getFormatId() {
		return formatId;
	}

	public byte[] getGlobalTransactionId() {
		return gtrid;
	}

	public boolean equals(Object arg0) {
		if (!(arg0 instanceof XidImpl))
			return false;
		XidImpl other = (XidImpl) arg0;
		if (formatId == other.formatId && Arrays.equals(gtrid, other.gtrid)
				&& Arrays.equals(bqual, other.bqual))
			return true;
		return false;
	}

	public int hashCode() {
		return toString().hashCode();
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("XidImpl(");
		sb.append("format=");
		sb.append(formatId);
		sb.append(",gtrid=");
		for (int i = 0; i < gtrid.length; i++)
			sb.append(Integer.toHexString(gtrid[i]));
		sb.append(",bqual=");
		for (int i = 0; i < gtrid.length; i++)
			sb.append(Integer.toHexString(gtrid[i]));
		sb.append(")");
		return sb.toString();
	}
}