/*
 * 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.felix.framework.security.util;

import java.io.File;
import java.io.FilePermission;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.security.AllPermission;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import org.apache.felix.framework.util.SecureAction;
import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.permissionadmin.PermissionInfo;

/**
 * A permission cache that uses permisssion infos as keys. Permission are created
 * from the parent classloader or any exported package. 
 */
// TODO: maybe use bundle events instead of soft/weak references
public final class Permissions
{
    private static final ClassLoader m_classLoader =
        Permissions.class.getClassLoader();

    private static final Map m_permissionCache = new HashMap();
    private static final Map m_permissions = new HashMap();
    private static final ReferenceQueue m_permissionsQueue =
        new ReferenceQueue();

    private static final ThreadLocal m_stack = new ThreadLocal();

    private final Map m_cache;
    private final ReferenceQueue m_queue;
    private final BundleContext m_context;
    private final PermissionInfo[] m_permissionInfos;
    private final boolean m_allPermission;
    private final SecureAction m_action;

    public static final AllPermission ALL_PERMISSION = new AllPermission();

    private static final PermissionInfo[] IMPLICIT =
        new PermissionInfo[] { new PermissionInfo(FilePermission.class
            .getName(), "-", "read,write,delete") };

    Permissions(PermissionInfo[] permissionInfos, BundleContext context,
        SecureAction action)
    {
        m_context = context;
        m_permissionInfos = permissionInfos;
        m_cache = new HashMap();
        m_queue = new ReferenceQueue();
        m_action = action;
        for (int i = 0; i < m_permissionInfos.length; i++)
        {
            if (m_permissionInfos[i].getType().equals(
                AllPermission.class.getName()))
            {
                m_allPermission = true;
                return;
            }
        }
        m_allPermission = false;
    }

    public Permissions(BundleContext context, SecureAction action)
    {
        m_context = context;
        m_permissionInfos = null;
        m_cache = null;
        m_queue = null;
        m_allPermission = true;
        m_action = action;
    }
    
    public PermissionInfo[] getImplicit(Bundle bundle)
    {
        return new PermissionInfo[] {
            IMPLICIT[0],
            new PermissionInfo(AdminPermission.class.getName(), "(id="
                + bundle.getBundleId() + ")", AdminPermission.METADATA) };
    }

    public Permissions getPermissions(PermissionInfo[] permissionInfos)
    {
        cleanUp(m_permissionsQueue, m_permissions);

        Permissions result = null;
        synchronized (m_permissions)
        {
            result = (Permissions) m_permissions.get(permissionInfos);
        }
        if (result == null)
        {
            result = new Permissions(permissionInfos, m_context, m_action);
            synchronized (m_permissions)
            {
                m_permissions.put(
                    new Entry(permissionInfos, m_permissionsQueue), result);
            }
        }
        return result;
    }

    private static final class Entry extends WeakReference
    {
        private final int m_hashCode;

        Entry(Object entry, ReferenceQueue queue)
        {
            super(entry, queue);
            m_hashCode = entry.hashCode();
        }

        Entry(Object entry)
        {
            super(entry);
            m_hashCode = entry.hashCode();
        }

        public Object get()
        {
            return super.get();
        }

        public int hashCode()
        {
            return m_hashCode;
        }

        public boolean equals(Object o)
        {
            if (o == null)
            {
                return false;
            }

            if (o == this)
            {
                return true;
            }

            Object entry = super.get();

            if (entry == null)
            {
                return false;
            }

            if (o instanceof Entry) 
            {
                return entry.equals(((Entry)o).get());
            } 
            else 
            {
                return false;
            }
        }
    }

    private static final class DefaultPermissionCollection extends
        PermissionCollection
    {
        private final Map m_perms = new HashMap();

        public void add(Permission perm)
        {
            synchronized (m_perms)
            {
                m_perms.put(perm, perm);
            }
        }

        public Enumeration elements()
        {
            throw new IllegalStateException("Not implemented");
        }

        public boolean implies(Permission perm)
        {
            Map perms = null;

            synchronized (m_perms)
            {
                perms = m_perms;
            }

            Permission permission = (Permission) perms.get(perm);

            if ((permission != null) && permission.implies(perm))
            {
                return true;
            }

            for (Iterator iter = perms.values().iterator(); iter.hasNext();)
            {
                Permission current = (Permission) iter.next();
                if ((current != null) && (current != permission)
                    && current.implies(perm))
                {
                    return true;
                }
            }
            return false;
        }
    }

    private void cleanUp(ReferenceQueue queue, Map cache)
    {
        for (Entry entry = (Entry) queue.poll(); entry != null; entry =
            (Entry) queue.poll())
        {
            synchronized (cache)
            {
                cache.remove(entry);
            }
        }
    }

    /**
     * @param target the permission to be implied
     * @param bundle if not null then allow implicit permissions like file 
     *     access to local data area
     * @return true if the permission is implied by this permissions object.
     */
    public boolean implies(Permission target, Bundle bundle)
    {
        if (m_allPermission)
        {
            return true;
        }

        Class targetClass = target.getClass();

        cleanUp(m_queue, m_cache);

        if ((bundle != null) && targetClass == FilePermission.class)
        {
            for (int i = 0; i < m_permissionInfos.length; i++)
            {
                if (m_permissionInfos[i].getType().equals(
                    FilePermission.class.getName()))
                {
                    String postfix = "";
                    String name = m_permissionInfos[i].getName();
                    if (!"<<ALL FILES>>".equals(name)) 
                    {
                        if (name.endsWith("*") || name.endsWith("-"))
                        {
                            postfix = name.substring(name.length() - 1);
                            name = name.substring(0, name.length() - 1);
                        }
                        if (!(new File(name)).isAbsolute())
                        {
                            BundleContext context = bundle.getBundleContext();
                            if (context == null)
                            {
                                break;
                            }
                            name =
                                m_action.getAbsolutePath(new File(context.getDataFile(""), name));
                        }
                        if (postfix.length() > 0)
                        {
                            if ((name.length() > 0) && !name.endsWith("/"))
                            {
                                name += "/" + postfix;
                            }
                            else
                            {
                                name += postfix;
                            }
                        }
                    }
                    return createPermission(
                        new PermissionInfo(FilePermission.class.getName(),
                            name, m_permissionInfos[i].getActions()),
                        targetClass).implies(target);
                }
            }
            return false;
        }

        Object current = m_stack.get();

        if (current == null)
        {
            m_stack.set(targetClass);
        }
        else
        {
            if (current instanceof HashSet)
            {
                if (((HashSet) current).contains(targetClass))
                {
                    return false;
                }
                ((HashSet) current).add(targetClass);
            }
            else
            {
                if (current == targetClass)
                {
                    return false;
                }
                HashSet frame = new HashSet();
                frame.add(current);
                frame.add(targetClass);
                m_stack.set(frame);
                current = frame;
            }
        }

        try
        {
            SoftReference collectionEntry = null;

            PermissionCollection collection = null;

            synchronized (m_cache)
            {
                collectionEntry = (SoftReference) m_cache.get(targetClass);
            }

            if (collectionEntry != null)
            {
                collection = (PermissionCollection) collectionEntry.get();
            }

            if (collection == null)
            {
                collection = target.newPermissionCollection();

                if (collection == null)
                {
                    collection = new DefaultPermissionCollection();
                }

                for (int i = 0; i < m_permissionInfos.length; i++)
                {
                    PermissionInfo permissionInfo = m_permissionInfos[i];
                    String infoType = permissionInfo.getType();
                    String permissionType = targetClass.getName();

                    if (infoType.equals(permissionType))
                    {
                        Permission permission =
                            createPermission(permissionInfo, targetClass);

                        if (permission != null)
                        {
                            collection.add(permission);
                        }
                    }
                }

                synchronized (m_cache)
                {
                    m_cache.put(new Entry(target.getClass(), m_queue),
                        new SoftReference(collection));
                }
            }

            return collection.implies(target);
        }
        finally
        {
            if (current == null)
            {
                m_stack.set(null);
            }
            else
            {
                ((HashSet) current).remove(targetClass);
                if (((HashSet) current).isEmpty())
                {
                    m_stack.set(null);
                }
            }
        }
    }

    private Permission addToCache(String encoded, Permission permission)
    {
        if (permission == null)
        {
            return null;
        }

        synchronized (m_permissionCache)
        {
            Map inner = null;

            SoftReference ref = (SoftReference) m_permissionCache.get(encoded);
            if (ref != null)
            {
                inner = (Map) ref.get();
            }
            if (inner == null)
            {
                inner = new HashMap();
                m_permissionCache.put(encoded,
                    new SoftReference(inner, m_queue));
            }

            inner.put(new Entry(permission.getClass()), new Entry(permission));
        }

        return permission;
    }

    private Permission getFromCache(String encoded, Class target)
    {
        synchronized (m_permissionCache)
        {
            SoftReference ref = (SoftReference) m_permissionCache.get(encoded);
            if (ref != null)
            {
                Map inner = (Map) ref.get();
                if (inner != null)
                {
                    Entry entry = (Entry) inner.get(target);
                    if (entry != null)
                    {
                        Permission result = (Permission) entry.get();
                        if (result != null)
                        {
                            return result;
                        }
                        inner.remove(entry);
                    }
                    if (inner.isEmpty())
                    {
                        m_permissionCache.remove(encoded);
                    }
                }
                else
                {
                    m_permissionCache.remove(encoded);
                }
            }

        }

        return null;
    }

    private Permission createPermission(final PermissionInfo permissionInfo,
        final Class target)
    {
        return (Permission) AccessController.doPrivileged(new PrivilegedAction() {
            public Object run()
            {
        Permission cached = getFromCache(permissionInfo.getEncoded(), target);

        if (cached != null)
        {
            return cached;
        }

        try
        {
            if (m_classLoader.loadClass(target.getName()) == target)
            {
                return addToCache(permissionInfo.getEncoded(),
                    createPermission(permissionInfo.getName(), permissionInfo
                        .getActions(), target));
            }
        }
        catch (ClassNotFoundException e1)
        {
        }

        ServiceReference[] refs = null;
        try
        {
            refs =
                m_context.getServiceReferences(PackageAdmin.class.getName(),
                    null);
        }
        catch (InvalidSyntaxException e)
        {
        }
        if (refs != null)
        {
            for (int i = 0; i < refs.length; i++)
            {
                PackageAdmin admin =
                    (PackageAdmin) m_context.getService(refs[i]);

                if (admin != null)
                {
                    Permission result = null;
                    Bundle bundle = admin.getBundle(target);
                    if (bundle != null)
                    {
                        ExportedPackage[] exports =
                            admin.getExportedPackages(bundle);
                        if (exports != null)
                        {
                            String name = target.getName();
                            name = name.substring(0, name.lastIndexOf('.'));

                            for (int j = 0; j < exports.length; j++)
                            {
                                if (exports[j].getName().equals(name))
                                {
                                    result =
                                        createPermission(permissionInfo
                                            .getName(), permissionInfo
                                            .getActions(), target);
                                    break;
                                }
                            }
                        }
                    }

                    m_context.ungetService(refs[i]);

                    return addToCache(permissionInfo.getEncoded(), result);
                }
            }
        }

        return null;
        }});
    }

    private Permission createPermission(String name, String action, Class target)
    {
        try
        {
            return (Permission) m_action.getConstructor(target,
                new Class[] { String.class, String.class }).newInstance(
                new Object[] { name, action });
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return null;
    }
}
