/*
 * 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.sling.jcr.classloader.internal;

import java.util.Dictionary;
import java.util.Iterator;

import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;

import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.classloader.RepositoryClassLoaderProvider;
import org.osgi.framework.Bundle;
import org.osgi.service.component.ComponentContext;

/**
 * The <code>RepositoryClassLoaderProviderImpl</code> TODO
 *
 * @scr.component immediate="false" label="%loader.name"
 *      description="%loader.description"
 * @scr.property name="service.vendor" value="The Apache Software Foundation"
 * @scr.property name="service.description"
 *      value="Provides Repository ClassLoaders"
 * @scr.service servicefactory="true"
 */
public class RepositoryClassLoaderProviderImpl
        implements RepositoryClassLoaderProvider {

    /**
     * @scr.property values0="/var/classes"
     */
    public static final String CLASS_PATH_PROP = "classpath";

    /**
     * @scr.property valueRef="OWNER_DEFAULT"
     */
    public static final String OWNER_PROP = "owner";

    // JSP Class Loader class path will be injected to the class loader !
    private static final String[] CLASS_PATH_DEFAULT = { };

    private static final String OWNER_DEFAULT = "admin";

    private BidiMap loaders = new DualHashBidiMap();

    /**
     * @scr.reference
     */
    private SlingRepository repository;

    private String[] classPath;

    private String classLoaderOwner;

    private BundleProxyClassLoader parent;

    public ClassLoader getClassLoader(String owner) {
        String classLoaderOwner = this.getClassLoaderOwner(owner);
        RepositoryClassLoaderFacade loader =
            (RepositoryClassLoaderFacade) this.loaders.get(classLoaderOwner);
        if (loader == null) {
            loader = new RepositoryClassLoaderFacade(this, this.parent,
                classLoaderOwner, this.classPath);
            this.loaders.put(classLoaderOwner, loader);
        }

        // extend reference counter
        loader.ref();

        return loader;
    }

    public void ungetClassLoader(ClassLoader classLoader) {
        if (classLoader instanceof RepositoryClassLoaderFacade) {
            RepositoryClassLoaderFacade cl = (RepositoryClassLoaderFacade) classLoader;
            cl.deref();
        }
    }

    //---------- Support for RepositoryClassLoaderFacade ----------------------

    /* package */ Session getSession(String owner) throws RepositoryException {
        // get an administrative session for potentiall impersonation
        Session admin = this.repository.loginAdministrative(null);

        // do use the admin session, if the admin's user id is the same as owner
        if (admin.getUserID().equals(owner)) {
            return admin;
        }

        // else impersonate as the owner and logout the admin session again
        try {
            return admin.impersonate(new SimpleCredentials(owner, new char[0]));
        } finally {
            admin.logout();
        }
    }

    //---------- SCR Integration ----------------------------------------------

    protected void activate(ComponentContext componentContext) {
        Dictionary properties = componentContext.getProperties();

        Object prop = properties.get(CLASS_PATH_PROP);
        this.classPath = (prop instanceof String[]) ? (String[]) prop : CLASS_PATH_DEFAULT;

        prop = properties.get(OWNER_PROP);
        this.classLoaderOwner = (prop instanceof String)? (String) prop : OWNER_DEFAULT;

        Bundle owner = componentContext.getUsingBundle();

        // if there is no using bundle, we have an error !!
        if (owner == null) {
            throw new IllegalStateException("Using Bundle expected. Is this a servicefactory component ?");
        }

        this.parent = new BundleProxyClassLoader(owner, null);
    }

    protected void deactivate(ComponentContext componentContext) {
        for (Iterator ci=this.loaders.values().iterator(); ci.hasNext(); ) {
            RepositoryClassLoaderFacade cl = (RepositoryClassLoaderFacade) ci.next();
            cl.destroy();
            ci.remove();
        }

        this.parent = null;
    }

    protected void bindRepository(SlingRepository repository) {
        this.repository = repository;
    }

    protected void unbindRepository(SlingRepository repository) {
        this.repository = null;
    }

    //---------- internal -----------------------------------------------------

    private String getClassLoaderOwner(String userId) {
        return this.classLoaderOwner;
    }
}
