/*
 * Copyright (c) 2006, 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.enterprise.naming.impl;

import org.glassfish.api.admin.ProcessEnvironment;
import org.glassfish.api.admin.ProcessEnvironment.ProcessType;
import org.glassfish.api.naming.ComponentNamingUtil;
import org.glassfish.internal.api.Globals;
import org.glassfish.hk2.api.ServiceLocator;

import javax.naming.*;
import java.util.Hashtable;
import java.util.logging.Level;

import static com.sun.enterprise.naming.util.LogFacade.logger;

/**
 * This class is a context implementation for the java:comp namespace.
 * The context determines the component id from the invocation manager
 * of the component that is invoking the method and then looks up the
 * object in that component's local namespace.
 */
public final class JavaURLContext implements Context, Cloneable {
    private static GlassfishNamingManagerImpl namingManager;

    private Hashtable myEnv;
    //private Context ctx; XXX not needed ?
    private String myName = "";

    private SerialContext serialContext = null;

    /**
     * Create a context with the specified environment.
     */
    public JavaURLContext(Hashtable environment) throws NamingException {
        myEnv = (environment != null) ? (Hashtable) (environment.clone())
                : null;
    }

    /**
     * Create a context with the specified name+environment.
     * Called only from GlassfishNamingManager.
     */
    public JavaURLContext(String name, Hashtable env)
            throws NamingException {
        this(env);
        this.myName = name;
    }

    /**
     * this constructor is called from SerialContext class
     */
    public JavaURLContext(Hashtable env, SerialContext serialContext)
            throws NamingException {
        this(env);
        this.serialContext = serialContext;
    }

    public JavaURLContext( JavaURLContext ctx, SerialContext sctx ) {
        this.myName = ctx.myName ;
        this.myEnv = ctx.myEnv ;
        this.serialContext = sctx ;
    }

    static void setNamingManager(GlassfishNamingManagerImpl mgr) {
        namingManager = mgr;
    }

    /**
     * add SerialContext to preserve stickiness to cloned instance
     * why clone() : to avoid the case of multiple threads modifying
     * the context returned for ctx.lookup("java:com/env/ejb")
     */
    /**  STICKY context not enabled
    public JavaURLContext addStickyContext(SerialContext serialContext)
            throws NamingException {
        try {
            JavaURLContext jCtx = (JavaURLContext) this.clone();
            jCtx.serialContext = serialContext;
            return jCtx;
        } catch (java.lang.CloneNotSupportedException ex) {
            NamingException ne = new NamingException(
                    "problem with cloning javaURLContext instance");
            ne.initCause(ex);
            throw ne;
        }
    }
    **/

    /**
     * Lookup an object in the serial context.
     *
     * @return the object that is being looked up.
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public Object lookup(String name) throws NamingException {
        if (name.equals("")) {
            /**
             * javadocs for Context.lookup: If name is empty, returns a new
             * instance of this context (which represents the same naming
             * context as this context, but its environment may be modified
             * independently and it may be accessed concurrently).
             */
            return new JavaURLContext(myName, myEnv);
        }

        String fullName = name;
        if (!myName.equals("")) {
            if (myName.equals("java:"))
                fullName = myName + name;
            else
                fullName = myName + "/" + name;
        }

        try {
            Object obj = null;
            // If we know for sure it's an entry within an environment namespace
            if (isLookingUpEnv(fullName)) {
                // refers to a dependency defined by the application
                obj = namingManager.lookup(fullName, serialContext);
            } else {
                // It's either an application-defined dependency in a java:
                // namespace or a special EE platform object.
                // Check for EE platform objects first to prevent overriding.
                obj = NamedNamingObjectManager.tryNamedProxies(name);
                if (obj == null) {
                    // try GlassfishNamingManager
                    obj = namingManager.lookup(fullName, serialContext);
                }
            }

            if( obj == null ) {
                throw new NamingException("No object found for " + name);
            }

            return obj;
        } catch (NamingException ex) {

            ServiceLocator services = Globals.getDefaultHabitat();
            ProcessEnvironment processEnv = services.getService(ProcessEnvironment.class);
            if( fullName.startsWith("java:app/") &&
                processEnv.getProcessType() == ProcessType.ACC ) {

                // This could either be an attempt by an app client to access a portable
                // remote session bean JNDI name via the java:app namespace or a lookup of
                // an application-defined java:app environment dependency.  Try them in
                // that order.

                Context ic = namingManager.getInitialContext();
                String appName = (String) namingManager.getInitialContext().lookup("java:app/AppName");

                Object obj = null;

                if (!fullName.startsWith("java:app/env/")
                    || !"java:app/env".equals(fullName)) {
                    try {

                        // Translate the java:app name into the equivalent java:global name so that
                        // the lookup will be resolved by the server.
                        String newPrefix = "java:global/" + appName + "/";

                        int javaAppLength = "java:app/".length();
                        String globalLookup = newPrefix + fullName.substring(javaAppLength);

                        obj = ic.lookup(globalLookup);

                    } catch(NamingException javaappenvne) {
                        logger.log(Level.FINE, "Trying global version of java:app ejb lookup", javaappenvne);
                    }
                }

                if( obj == null ) {
                   ComponentNamingUtil compNamingUtil = services.getService(ComponentNamingUtil.class);
                   String internalGlobalJavaAppName =
                    compNamingUtil.composeInternalGlobalJavaAppName(appName, fullName);

                    obj = ic.lookup(internalGlobalJavaAppName);
                }

                if( obj == null ) {
                    throw new NamingException("No object found for " + name);
                }

                return obj;

            }

            throw ex;
        } catch (Exception ex) {
            throw (NamingException) (new NameNotFoundException(
                    "No object bound for " + fullName)).initCause(ex);
        }
    }

    /**
     * Lookup a name in either the cosnaming or serial context.
     *
     * @return the object that is being looked up.
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public Object lookup(Name name) throws NamingException {
        // Flat namespace; no federation; just call string version
        return lookup(name.toString());
    }

    /**
     * Bind an object in the namespace. Binds the reference to the
     * actual object in either the cosnaming or serial context.
     *
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public void bind(String name, Object obj) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    /**
     * Bind an object in the namespace. Binds the reference to the
     * actual object in either the cosnaming or serial context.
     *
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public void bind(Name name, Object obj) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    /**
     * Rebind an object in the namespace. Rebinds the reference to the
     * actual object in either the cosnaming or serial context.
     *
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public void rebind(String name, Object obj) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    /**
     * Rebind an object in the namespace. Rebinds the reference to the
     * actual object in either the cosnaming or serial context.
     *
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public void rebind(Name name, Object obj) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    /**
     * Unbind an object from the namespace.
     *
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public void unbind(String name) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    /**
     * Unbind an object from the namespace.
     *
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public void unbind(Name name) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    /**
     * The rename operation is not supported by this context. It throws
     * an OperationNotSupportedException.
     */
    @Override
    public void rename(String oldname, String newname) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    /**
     * The rename operation is not supported by this context. It throws
     * an OperationNotSupportedException.
     */
    @Override
    public void rename(Name oldname, Name newname)
            throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    /**
     * The destroySubcontext operation is not supported by this context.
     * It throws an OperationNotSupportedException.
     */
    @Override
    public void destroySubcontext(String name) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    /**
     * The destroySubcontext operation is not supported by this context.
     * It throws an OperationNotSupportedException.
     */
    @Override
    public void destroySubcontext(Name name) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    @Override
    public Context createSubcontext(String name) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }

    @Override
    public Context createSubcontext(Name name) throws NamingException {
        throw new NamingException("java:comp namespace cannot be modified");
    }


    /**
     * Lists the contents of a context or subcontext. The operation is
     * delegated to the serial context.
     *
     * @return an enumeration of the contents of the context.
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public NamingEnumeration<NameClassPair> list(String name)
            throws NamingException {
        if (name.equals("")) {
            // listing this context
            if (namingManager == null)
                throw new NamingException();
            return namingManager.list(myName);
        }

        // Check if 'name' names a context
        Object target = lookup(name);
        if (target instanceof Context) {
            return ((Context) target).list("");
        }
        throw new NotContextException(name + " cannot be listed");
    }

    /**
     * Lists the contents of a context or subcontext. The operation is
     * delegated to the serial context.
     *
     * @return an enumeration of the contents of the context.
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public NamingEnumeration<NameClassPair> list(Name name)
            throws NamingException {
        // Flat namespace; no federation; just call string version
        return list(name.toString());
    }

    /**
     * Lists the bindings of a context or subcontext. The operation is
     * delegated to the serial context.
     *
     * @return an enumeration of the bindings of the context.
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public NamingEnumeration<Binding> listBindings(String name)
            throws NamingException {
        if (name.equals("")) {
            // listing this context
            if (namingManager == null)
                throw new NamingException();
            return namingManager.listBindings(myName);
        }

        // Perhaps 'name' names a context
        Object target = lookup(name);
        if (target instanceof Context) {
            return ((Context) target).listBindings("");
        }
        throw new NotContextException(name + " cannot be listed");
    }

    /**
     * Lists the bindings of a context or subcontext. The operation is
     * delegated to the serial context.
     *
     * @return an enumeration of the bindings of the context.
     * @throws NamingException if there is a naming exception.
     */
    @Override
    public NamingEnumeration<Binding> listBindings(Name name)
            throws NamingException {
        // Flat namespace; no federation; just call string version
        return listBindings(name.toString());
    }

    /**
     * This context does not treat links specially. A lookup operation is
     * performed.
     */
    @Override
    public Object lookupLink(String name) throws NamingException {
        // This flat context does not treat links specially
        return lookup(name);
    }

    /**
     * This context does not treat links specially. A lookup operation is
     * performed.
     */
    @Override
    public Object lookupLink(Name name) throws NamingException {
        // Flat namespace; no federation; just call string version
        return lookupLink(name.toString());
    }

    /**
     * Return the name parser for the specified name.
     *
     * @return the NameParser instance.
     * @throws NamingException if there is an exception.
     */
    @Override
    public NameParser getNameParser(String name)
            throws NamingException {
        if (namingManager == null)
            throw new NamingException();
        return namingManager.getNameParser();
    }

    /**
     * Return the name parser for the specified name.
     *
     * @return the NameParser instance.
     * @throws NamingException if there is an exception.
     */
    @Override
    public NameParser getNameParser(Name name) throws NamingException {
        // Flat namespace; no federation; just call string version
        return getNameParser(name.toString());
    }

    @Override
    public String composeName(String name, String prefix)
            throws NamingException {
        Name result = composeName(new CompositeName(name),
                new CompositeName(prefix));
        return result.toString();
    }

    @Override
    public Name composeName(Name name, Name prefix)
            throws NamingException {
        Name result = (Name) (prefix.clone());
        result.addAll(name);
        return result;
    }

    /**
     * Add a property to the environment.
     */
    @Override
    public Object addToEnvironment(String propName, Object propVal)
            throws NamingException {
        if (myEnv == null) {
            myEnv = new Hashtable(5, 0.75f);
        }
        return myEnv.put(propName, propVal);
    }

    /**
     * Remove a property from the environment.
     */
    @Override
    public Object removeFromEnvironment(String propName)
            throws NamingException {
        if (myEnv == null) {
            return null;
        }
        return myEnv.remove(propName);
    }

    /**
     * Get the context's environment.
     */
    @Override
    public Hashtable getEnvironment() throws NamingException {
        if (myEnv == null) {
            // Must return non-null
            myEnv = new Hashtable(3, 0.75f);
        }
        return myEnv;
    }

    /**
     * New JNDI 1.2 operation.
     */
    @Override
    public void close() throws NamingException {
        myEnv = null;
    }

    /**
     * Return the name of this context within the namespace.  The name
     * can be passed as an argument to (new InitialContext()).lookup()
     * to reproduce this context.
     */
    @Override
    public String getNameInNamespace() throws NamingException {
        return myName;
    }


  private boolean isLookingUpEnv(String fullName) {
    boolean result = false;
    if (fullName.startsWith("java:comp/env/")
        || fullName.startsWith("java:module/env/")
        || fullName.startsWith("java:app/env/")) {
      result = true;
    } else if ("java:comp/env".equals(fullName)
        || "java:module/env".equals(fullName)
        || "java:app/env".equals(fullName)) {
      result = true;
    }
    return result;
  }

}


