/* 
 * 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.bundlerepository.impl;

import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.felix.bundlerepository.Capability;
import org.apache.felix.bundlerepository.DataModelHelper;
import org.apache.felix.bundlerepository.Repository;
import org.apache.felix.bundlerepository.RepositoryAdmin;
import org.apache.felix.bundlerepository.Requirement;
import org.apache.felix.bundlerepository.Resolver;
import org.apache.felix.bundlerepository.Resource;
import org.apache.felix.utils.collections.MapToDictionary;
import org.apache.felix.utils.log.Logger;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;

public class RepositoryAdminImpl implements RepositoryAdmin
{
    private final BundleContext m_context;
    private final Logger m_logger;
    private final SystemRepositoryImpl m_system;
    private final LocalRepositoryImpl m_local;
    private final DataModelHelper m_helper = new DataModelHelperImpl();
    private Map m_repoMap = new LinkedHashMap();
    private boolean m_initialized = false;

    // Reusable comparator for sorting resources by name.
    private Comparator m_nameComparator = new ResourceComparator();

    public static final String REPOSITORY_URL_PROP = "obr.repository.url";
    public static final String EXTERN_REPOSITORY_TAG = "extern-repositories";

    public RepositoryAdminImpl(BundleContext context, Logger logger)
    {
        m_context = context;
        m_logger = logger;
        m_system = new SystemRepositoryImpl(context, logger);
        m_local = new LocalRepositoryImpl(context, logger);
    }

    public DataModelHelper getHelper()
    {
        return m_helper;
    }

    public Repository getLocalRepository()
    {
        return m_local;
    }

    public Repository getSystemRepository()
    {
        return m_system;
    }

    public void dispose()
    {
        m_local.dispose();
    }

    public Repository addRepository(String uri) throws Exception
    {
        return addRepository(new URL(uri));
    }

    public Repository addRepository(URL url) throws Exception
    {
        return addRepository(url, Integer.MAX_VALUE);
    }

    public synchronized RepositoryImpl addRepository(final URL url, int hopCount) throws Exception
    {
        initialize();

        // If the repository URL is a duplicate, then we will just
        // replace the existing repository object with a new one,
        // which is effectively the same as refreshing the repository.
        try
        {
            RepositoryImpl repository = (RepositoryImpl) AccessController.doPrivileged(new PrivilegedExceptionAction()
            {
                public Object run() throws Exception
                {
                    return m_helper.repository(url);
                }
            });
            m_repoMap.put(url.toExternalForm(), repository);

            // resolve referrals
            hopCount--;
            if (hopCount > 0 && repository.getReferrals() != null)
            {
                for (int i = 0; i < repository.getReferrals().length; i++)
                {
                    Referral referral = repository.getReferrals()[i];

                    URL referralUrl = new URL(url, referral.getUrl());
                    hopCount = (referral.getDepth() > hopCount) ? hopCount : referral.getDepth();

                    addRepository(referralUrl, hopCount);
                }
            }

            return repository;
        }
        catch (PrivilegedActionException ex)
        {
            throw (Exception) ex.getCause();
        }

    }

    public synchronized boolean removeRepository(String uri)
    {
        initialize();
        
        try
        {
            URL url = new URL(uri);
            return m_repoMap.remove(url.toExternalForm()) != null;
        }
        catch (MalformedURLException e)
        {
            return m_repoMap.remove(uri) != null;
        }
    }

    public synchronized Repository[] listRepositories()
    {
        initialize();

        return (Repository[]) m_repoMap.values().toArray(new Repository[m_repoMap.size()]);
    }

    public synchronized Resolver resolver()
    {
        initialize();

        List repositories = new ArrayList();
        repositories.add(m_system);
        repositories.add(m_local);
        repositories.addAll(m_repoMap.values());
        return resolver((Repository[]) repositories.toArray(new Repository[repositories.size()]));
    }

    public synchronized Resolver resolver(Repository[] repositories)
    {
        initialize();

        if (repositories == null)
        {
            return resolver();
        }
        return new ResolverImpl(m_context, repositories, m_logger);
    }

    public synchronized Resource[] discoverResources(String filterExpr) throws InvalidSyntaxException
    {
        initialize();

        Filter filter = filterExpr != null ? m_helper.filter(filterExpr) : null;
        Resource[] resources;
        MapToDictionary dict = new MapToDictionary(null);
        Repository[] repos = listRepositories();
        List matchList = new ArrayList();
        for (int repoIdx = 0; (repos != null) && (repoIdx < repos.length); repoIdx++)
        {
            resources = repos[repoIdx].getResources();
            for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++)
            {
                dict.setSourceMap(resources[resIdx].getProperties());
                if (filter == null || filter.match(dict))
                {
                    matchList.add(resources[resIdx]);
                }
            }
        }

        // Convert matching resources to an array an sort them by name.
        resources = (Resource[]) matchList.toArray(new Resource[matchList.size()]);
        Arrays.sort(resources, m_nameComparator);
        return resources;
    }

    public synchronized Resource[] discoverResources(Requirement[] requirements)
    {
        initialize();

        Resource[] resources = null;
        Repository[] repos = listRepositories();
        List matchList = new ArrayList();
        for (int repoIdx = 0; (repos != null) && (repoIdx < repos.length); repoIdx++)
        {
            resources = repos[repoIdx].getResources();
            for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++)
            {
                boolean match = true;
                for (int reqIdx = 0; (requirements != null) && (reqIdx < requirements.length); reqIdx++)
                {
                    boolean reqMatch = false;
                    Capability[] caps = resources[resIdx].getCapabilities();
                    for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
                    {
                        if (requirements[reqIdx].isSatisfied(caps[capIdx]))
                        {
                            reqMatch = true;
                            break;
                        }
                    }
                    match &= reqMatch;
                    if (!match)
                    {
                        break;
                    }
                }
                if (match)
                {
                    matchList.add(resources[resIdx]);
                }
            }
        }

        // Convert matching resources to an array an sort them by name.
        resources = (Resource[]) matchList.toArray(new Resource[matchList.size()]);
        Arrays.sort(resources, m_nameComparator);
        return resources;
    }

    private void initialize()
    {
        if (m_initialized)
        {
            return;
        }
        m_initialized = true;

        // First check the repository URL config property.
        String urlStr = m_context.getProperty(REPOSITORY_URL_PROP);
        if (urlStr != null)
        {
            StringTokenizer st = new StringTokenizer(urlStr);
            if (st.countTokens() > 0)
            {
                while (st.hasMoreTokens())
                {
                    final String token = st.nextToken();
                    try
                    {
                        addRepository(token);
                    }
                    catch (Exception ex)
                    {
                        m_logger.log(
                            Logger.LOG_WARNING,
                            "Repository url " + token + " cannot be used. Skipped.",
                            ex);
                    }
                }
            }
        }

    }

}
