/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * 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.ejte.ccl.reporter;

import java.rmi.RemoteException;
import javax.rmi.PortableRemoteObject;
import jakarta.ejb.*;
import jakarta.transaction.*;
import javax.naming.*;

import java.sql.*;
import javax.sql.*;
import java.util.*;
import java.io.Serializable;
import java.util.logging.*;

public class EnterpriseBeanLogger implements Serializable{
  public static final int PASS_BY_REFERENCE = 0;
  public static final int PASS_BY_VALUE = 1;

  public static String EJB_REF_LOCAL_NAME = "ejbRefLocalName";
  public static String EJB_REF_NAME = "ejbRefName";
  public static String EJB_RELATIONSHIP_NAME = "ejbRelationshipName";
  public static String EJB_RELATIONSHIP_NAME_2 = "ejbRelationshipName2";
  private static Logger logger = Logger.getLogger("bank.admin");
  private static ConsoleHandler ch = new ConsoleHandler();

  /*abstract public Collection getLocalContracts();
  abstract public Collection getRemoteContracts();
   **/

  protected PortableAdapter[] adapterHome;

  protected boolean dualMode = false;

  protected boolean doPassByValue = true;

  protected int REMOTE_EJB = 0;
  protected int LOCAL_EJB = 1;

  protected boolean outputXML = true;

  private static int instanceCreated;
  protected String instanceName;

  protected boolean prepareLocalAndRemoteObject(String localRef, String remoteRef) throws jakarta.ejb.CreateException {
    instanceCreated++;
    instanceName = getClass().getName() + "____________________" + instanceCreated;

    adapterHome = new PortableAdapter[2];
    Context ic = null;
    try{
      ic = new InitialContext();

      String mode = ic.lookup("java:comp/env/toXML").toString().toLowerCase();
      if (mode.compareTo("false") == 0){
        outputXML = false;
      }
      toXML("toXML", mode);

    } catch(java.lang.Exception ex){
      toXML("toXML", "true");
    }

    try{
      ic = new InitialContext();
      String mode = ic.lookup("java:comp/env/passBy").toString().toLowerCase();
      if (mode.compareTo("both") == 0){
        dualMode = true;
      } else if (mode.compareTo("value") != 0){
        doPassByValue = false;
      }
      toXML("passBy", mode);

    } catch(java.lang.Exception ex){
      toXML("exception",ex.getMessage());
      toXML("passBy", "true");
    }

    Object objref = null;

    if ( (dualMode == true || doPassByValue) && remoteRef.compareTo("") != 0){
      try{
        toXML("remote interface",remoteRef);
        objref = ic.lookup(remoteRef);

        adapterHome[REMOTE_EJB] = (PortableAdapter)PortableRemoteObject.narrow(objref, PortableAdapter.class);
        toXML("Remote interface","Looked up remote interface");
      } catch(java.lang.Exception ex){
        logLocalXMLException(ex,"prepareLocalAndRemoteObject - remote");
      }
    } else {
      REMOTE_EJB = 0;
    }

    if (dualMode == true || !doPassByValue){
      if (dualMode == false){
        LOCAL_EJB = 0;
      }

      try{
          // Get another object just to be sure <TEST>
          ic = new InitialContext();

          toXML("local interface",localRef);
          toXML("local interface",ic.lookup(localRef).toString());
          adapterHome[LOCAL_EJB] = (PortableAdapter)ic.lookup(localRef);
      } catch(javax.naming.NamingException ex){
          logLocalXMLException(ex,"prepareLocalAndRemoteObject - local");
      }
    } else {
        LOCAL_EJB = 0;
    }

    toXML("REMOTE_EJB" , String.valueOf(REMOTE_EJB));
    toXML("LOCAL_EJB" , String.valueOf(LOCAL_EJB));
    return true;
  }

  public String lookupProperty(String s) throws javax.naming.NamingException{
    Context ic = new InitialContext();
    String l = ic.lookup("java:comp/env/" + s).toString();
    toXML("lookup",l);
    return l;
  }


  public String toXML(String value){
    return toXML("debugger",value);
  }

  /**
    * Static method. Very useful for local interface (but not recommended).
    */
  public String toXML(String tag, Object value){
    StringBuffer xml = new StringBuffer();
    xml.append("\n<log time=" + java.util.Calendar.getInstance().getTime().toString()+ ">\n");
    xml.append("\t<class>" + getClass().getName() + "</class>\n");
    xml.append("\t<" + tag + ">" + value.toString() + "</" + tag + ">\n");
    xml.append("</log>");

    /*if (outputXML) System.err.println(xml);
    return xml.toString();*/
    if (outputXML) logger.info(xml.toString());
    return xml.toString();
  }

  public void logLocalXMLException(java.lang.Exception ex, Object msg){
    if (outputXML){
      toXML("exception", msg.toString() + ": " + ex.getMessage());
      ex.printStackTrace(System.err);
      toXML("exception","---NOT THROWN TO CLIENT---");
    }
  }

  public void logXMLException(java.lang.Exception ex, Object msg){
    if (outputXML){
      toXML("exception", msg.toString() + ": " + ex.getMessage());
      ex.printStackTrace(System.err);
    }
  }

  public void doPassBy(int mode){
    if (mode == EnterpriseBeanLogger.PASS_BY_VALUE)
      doPassByValue = true;
    else
      doPassByValue = false;
  }

  public void setDualAccess(boolean b){
    dualMode = b;
  }

  public boolean isDualAccess(){
    return dualMode;
  }

  public PortableAdapter getLocalHome(){
    return adapterHome[LOCAL_EJB];
  }

  public PortableAdapter getRemoteHome(){
    return adapterHome[REMOTE_EJB];
  }

}
