/*
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 * Copyright 2021 Contributors to the Eclipse Foundation
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.enterprise.resource;

import com.sun.appserv.connectors.internal.api.PoolingException;
import com.sun.enterprise.connectors.ConnectorRuntime;
import com.sun.enterprise.resource.allocator.ResourceAllocator;
import com.sun.enterprise.resource.listener.ConnectionEventListener;
import com.sun.enterprise.resource.listener.LocalTxConnectionEventListener;
import com.sun.enterprise.resource.pool.PoolManager;
import com.sun.enterprise.transaction.api.JavaEETransaction;
import com.sun.enterprise.transaction.api.JavaEETransactionManager;
import com.sun.enterprise.transaction.api.TransactionConstants;
import com.sun.logging.LogDomains;
import org.glassfish.resourcebase.resources.api.PoolInfo;

import jakarta.resource.spi.ManagedConnection;
import jakarta.resource.spi.ResourceAllocationException;
import jakarta.transaction.SystemException;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Tony Ng, Jagadish Ramu
 *
 */
public class ConnectorXAResource implements XAResource {

    private Object userHandle;
    private ResourceSpec spec;
    private PoolInfo poolInfo;
    private ResourceAllocator alloc;
    private PoolManager poolMgr;
    private ManagedConnection localConnection;
    private ClientSecurityInfo info;
    private ConnectionEventListener listener;
    private ResourceHandle localHandle_;
    private JavaEETransaction associatedTransaction;

    // Create logger object per Java SDK 1.4 to log messages
    // introduced Santanu De, Sun Microsystems, March 2002

    static Logger _logger = LogDomains.getLogger(ConnectorXAResource.class, LogDomains.RSR_LOGGER);

    public ConnectorXAResource(ResourceHandle handle,
                               ResourceSpec spec,
                               com.sun.enterprise.resource.allocator.ResourceAllocator alloc,
                               ClientSecurityInfo info ) {

        // initially userHandle is associated with mc
        this.poolMgr = ConnectorRuntime.getRuntime().getPoolManager();
        this.userHandle = null;
        this.spec = spec;
        this.poolInfo = spec.getPoolInfo();
        this.alloc = alloc;
        this.info = info;
        localConnection = (ManagedConnection) handle.getResource();
        localHandle_ = handle;
    }

    public void setUserHandle(Object userHandle) {
        this.userHandle = userHandle;
    }

    private void handleResourceException(Exception ex)
        throws XAException {
        _logger.log(Level.SEVERE,"poolmgr.system_exception",ex);
        XAException xae = new XAException(ex.toString());
        xae.errorCode = XAException.XAER_RMERR;
        throw xae;
    }

    public void commit(Xid xid, boolean onePhase) throws XAException {
        try {
            ResourceHandle handle = getResourceHandle();
            ManagedConnection mc = (ManagedConnection) handle.getResource();
            mc.getLocalTransaction().commit();
        } catch (Exception ex) {
            handleResourceException(ex);
        }finally{
            resetAssociation();
            resetAssociatedTransaction();
        }
    }


    public void start(Xid xid, int flags) throws XAException {
        try {
            ResourceHandle handle = getResourceHandle();
            if (!localHandle_.equals(handle)) {
                ManagedConnection mc = (ManagedConnection) handle.getResource();
                mc.associateConnection(userHandle);
                LocalTxConnectionEventListener l =
                        (com.sun.enterprise.resource.listener.LocalTxConnectionEventListener) handle.getListener();
                if(_logger.isLoggable(Level.FINE)){
                    _logger.log(Level.FINE, "connection_sharing_start",  userHandle);
                }
                l.associateHandle(userHandle, localHandle_);
            } else{
                 associatedTransaction = getCurrentTransaction();
            }
        } catch (Exception ex) {
            handleResourceException(ex);
        }
    }

    public void end(Xid xid, int flags) throws XAException {
        if (_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE, "connection_sharing_end");
        }
        try {
            ResourceHandle handleInTransaction = getResourceHandle();
            if (!localHandle_.equals(handleInTransaction)) {
                LocalTxConnectionEventListener l = (LocalTxConnectionEventListener) handleInTransaction.getListener();

                ResourceHandle handle = l.removeAssociation(userHandle);
                if (handle != null) { // not needed, just to be sure.
                    ManagedConnection associatedConnection = (ManagedConnection) handle.getResource();
                    associatedConnection.associateConnection(userHandle);
                    if (_logger.isLoggable(Level.FINE)) {
                        _logger.log(Level.FINE, "connection_sharing_reset_association",
                                userHandle);
                    }
                }
            }
        } catch (Exception e) {
            handleResourceException(e);
        }
    }

    public void forget(Xid xid) throws XAException {
        if(_logger.isLoggable(Level.FINE)) {
        _logger.fine("Well, forget is called for xid :"+xid);
        }
        // no-op
    }

    public int getTransactionTimeout() throws XAException {
        return 0;
    }

    public boolean isSameRM(XAResource other) throws XAException {
        if (this == other) return true;
        if (other == null) return false;
        if (other instanceof ConnectorXAResource) {
            ConnectorXAResource obj = (ConnectorXAResource) other;
            return (this.spec.equals(obj.spec) &&
                    this.info.equals(obj.info));
        } else {
            return false;
        }
    }

    public int prepare(Xid xid) throws XAException {
        return TransactionConstants.LAO_PREPARE_OK;
    }

    public Xid[] recover(int flag) throws XAException {
        return new Xid[0];
    }

    public void rollback(Xid xid) throws XAException {
        try {
        ResourceHandle handle = getResourceHandle();
        ManagedConnection mc = (ManagedConnection) handle.getResource();
            mc.getLocalTransaction().rollback();
        } catch (Exception ex) {
            handleResourceException(ex);
        }finally{
            resetAssociation();
            resetAssociatedTransaction();
        }
    }

    public boolean setTransactionTimeout(int seconds) throws XAException {
        return false;
    }

    private ResourceHandle getResourceHandle() throws PoolingException {
        try {
            ResourceHandle h = null;
            JavaEETransaction j2eetran = getCurrentTransaction();
            if (j2eetran == null) {      //Only if some thing is wrong with tx manager.
                h = localHandle_;        //Just return the local handle.
            } else {
                h = (ResourceHandle)j2eetran.getNonXAResource();
            //make sure that if local-tx resource is set as 'unshareable', only one resource
            //can be acquired. If the resource in question is not the one in transaction, fail
            if(!localHandle_.isShareable()){
                   if(h != localHandle_){
                        throw new ResourceAllocationException("Cannot use more than one local-tx resource in unshareable scope");
                    }
                }
            }
            if (h.getResourceState().isUnenlisted()) {
                ManagedConnection mc = (ManagedConnection) h.getResource();
                // begin the local transaction if first time
                // this ManagedConnection is used in this JTA transaction
                mc.getLocalTransaction().begin();
            }
            return h;
        } catch (Exception ex) {
            _logger.log(Level.SEVERE, "poolmgr.system_exception", ex);
            throw new PoolingException(ex.toString(), ex);
        }
    }

    private JavaEETransaction getCurrentTransaction() throws SystemException {
         JavaEETransactionManager txMgr = ConnectorRuntime.getRuntime().getTransactionManager();
         return (JavaEETransaction) txMgr.getTransaction();
    }

    private void resetAssociation() throws XAException{
        try {
        ResourceHandle handle = getResourceHandle();

            LocalTxConnectionEventListener l = (LocalTxConnectionEventListener)handle.getListener();
            //Get all associated Handles and reset their ManagedConnection association.
            Map associatedHandles = l.getAssociatedHandles();
            if(associatedHandles != null ){
                Set<Map.Entry> userHandles = associatedHandles.entrySet();
                for(Map.Entry userHandleEntry : userHandles ){
                    ResourceHandle associatedHandle = (ResourceHandle)userHandleEntry.getValue();
                    ManagedConnection associatedConnection = (ManagedConnection)associatedHandle.getResource();
                    associatedConnection.associateConnection(userHandleEntry.getKey());
                    if(_logger.isLoggable(Level.FINE)){
                        _logger.log(Level.FINE, "connection_sharing_reset_association",
                                userHandleEntry.getKey());
                    }
                }
                //all associated handles are mapped back to their actual Managed Connection. Clear the associations.
                associatedHandles.clear();
            }

        } catch (Exception ex) {
            handleResourceException(ex);
        }
    }

    public JavaEETransaction getAssociatedTransaction(){
         return associatedTransaction;
    }

    private void resetAssociatedTransaction(){
         associatedTransaction = null;
    }
}
