/*

   Derby - Class org.apache.derbyTesting.junit.XATestUtil

   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.derbyTesting.junit;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;

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

// Note: this class is used as indicator class in sysinfo for the 
// presence of org.apache.derbyTesting package classes.
public class XATestUtil {
    
    /**
     * Return a new Xid for testing.
    */
    public static Xid getXid(int formatId, int b1, int b2) {
        byte[] globalId = new byte[Xid.MAXGTRIDSIZE];
        byte[] branchId = new byte[Xid.MAXBQUALSIZE];

        for (int i = 0; i < globalId.length; i++) {
            globalId[i] = (byte) (b1 + i);
        }

        for (int i = 0; i < branchId.length; i++) {
            branchId[i] = (byte) (b2 + i);
        }

        return getXid(formatId, globalId, branchId);
    }

    public static Xid getXid(int formatId, byte[] globalId, byte[] branchId) {
        return new utilXid(formatId, globalId, branchId);
    }
    
    /**
     * Dump an unexpected XAException.
     * @param tag Useful info to print
     * @param xae The exception
     */
    public static void dumpXAException(String tag, XAException xae) {

        System.out.println(tag + " : XAException - " + xae.getMessage()
                + " errorCode " + errorCode(xae));
        xae.printStackTrace(System.out);
    }

    /**
     * Create a view that allows useful inspection of the active
     * global transactions.
    */
    public static void createXATransactionView(Statement s) throws SQLException
    {
        s.execute(
                "create view XATESTUTIL.global_xactTable as " +
                "select  cast(global_xid as char(2)) as gxid," +
                " status, " +
                " CAST (case when first_instant is NULL then 'NULL' else 'false' end AS VARCHAR(8)) as readOnly, " +
                " cast (username as char(10)) as username, type " +
                " from syscs_diag.transaction_table");
    }
    
    /**
     * Display the active global transactions.
     * @param conn
     * @throws SQLException
     */
    public static void checkXATransactionView(Connection conn,String[][] expectedRows) throws SQLException
    {
        Statement s = conn.createStatement();
        ResultSet rs = s.executeQuery(
                "select * from XATESTUTIL.global_xactTable where gxid is not null order by gxid");
        if (expectedRows == null)
            JDBC.assertEmpty(rs);
        else
            JDBC.assertUnorderedResultSet(rs, expectedRows);
        rs.close();
    }
    
    /**
     * Return a string for the error code of the XAException.
    */
    public static String errorCode(XAException e)
    {
        String error;
        switch(e.errorCode)
        {
        case XAException.XA_HEURCOM : error = "XA_HEURCOM "; break;
        case XAException.XA_HEURHAZ : error = "XA_HEURHAZ"; break;
        case XAException.XA_HEURMIX : error = "XA_HEURMIX"; break;
        case XAException.XA_HEURRB : error = "XA_HEURRB "; break;
        case XAException.XA_NOMIGRATE : error = "XA_NOMIGRATE "; break;
        case XAException.XA_RBCOMMFAIL : error = "XA_RBCOMMFAIL "; break;
        case XAException.XA_RBDEADLOCK : error = "XA_RBDEADLOCK "; break;
        case XAException.XA_RBINTEGRITY : error = "XA_RBINTEGRITY "; break;
        case XAException.XA_RBOTHER : error = "XA_RBOTHER "; break;
        case XAException.XA_RBPROTO : error = "XA_RBPROTO "; break;
        case XAException.XA_RBROLLBACK : error = "XA_RBROLLBACK "; break;
        case XAException.XA_RBTIMEOUT : error = "XA_RBTIMEOUT "; break;
        case XAException.XA_RBTRANSIENT : error = "XA_RBTRANSIENT "; break;
        case XAException.XA_RDONLY : error = "XA_RDONLY "; break;
        case XAException.XA_RETRY : error = "XA_RETRY "; break;
        case XAException.XAER_ASYNC : error = "XAER_ASYNC "; break;
        case XAException.XAER_DUPID : error = "XAER_DUPID "; break;
        case XAException.XAER_INVAL : error = "XAER_INVAL "; break;
        case XAException.XAER_NOTA : error = "XAER_NOTA "; break;
        case XAException.XAER_OUTSIDE : error = "XAER_OUTSIDE "; break;
        case XAException.XAER_PROTO : error = "XAER_PROTO "; break;
        case XAException.XAER_RMERR : error = "XAER_RMERR "; break;
        case XAException.XAER_RMFAIL : error = "XAER_RMFAIL "; break;
        default: error = Integer.toString(e.errorCode); break;
        }        
        return error;
    }
    
}
/**
 * Simple utility class implementation of Xid for tests.
 *
 */
class utilXid implements Xid, Serializable {
    private static final long serialVersionUID = 64467338100036L;

    private final int format_id;

    private byte[] global_id;

    private byte[] branch_id;

    utilXid(int format_id, byte[] global_id, byte[] branch_id) {
        this.format_id = format_id;
        this.global_id = global_id;
        this.branch_id = branch_id;
    }

    /**
     * Obtain the format id part of the Xid.
     * <p>
     *
     * @return Format identifier. O means the OSI CCR format.
     **/
    public int getFormatId() {
        return (format_id);
    }

    /**
     * Obtain the global transaction identifier part of XID as an array of 
     * bytes.
     * <p>
     *
     * @return A byte array containing the global transaction identifier.
     **/
    public byte[] getGlobalTransactionId() {
        return (global_id);
    }

    /**
     * Obtain the transaction branch qualifier part of the Xid in a byte array.
     * <p>
     *
     * @return A byte array containing the branch qualifier of the transaction.
     **/
    public byte[] getBranchQualifier() {
        return (branch_id);
    }

    public boolean equals(Object obj) {
        boolean ret = false;

        if (obj instanceof utilXid) {
            utilXid that = (utilXid) obj;
            ret = this.format_id == that.format_id &&
                    Arrays.equals(this.global_id, that.global_id) &&
                    Arrays.equals(this.branch_id, that.branch_id);
        }

        return ret;
    }

    public int hashCode() {
        int hash = 7;
        hash = 41 * hash + this.format_id;
        hash = 41 * hash + Arrays.hashCode(this.global_id);
        hash = 41 * hash + Arrays.hashCode(this.branch_id);
        return hash;
    }
}
