/*
 * 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.aries.blueprint.namespace;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.aries.blueprint.ComponentDefinitionRegistry;
import org.apache.aries.blueprint.ComponentNameAlreadyInUseException;
import org.apache.aries.blueprint.Interceptor;
import org.apache.aries.blueprint.reflect.PassThroughMetadataImpl;
import org.osgi.service.blueprint.reflect.ComponentMetadata;
import org.osgi.service.blueprint.reflect.Target;

/**
 * ComponentDefinitionRegistry implementation.
 *
 * This implementation uses concurrent lists and maps to store components and converters metadata
 * to allow its use by concurrent threads. 
 *
 * @version $Rev: 922829 $, $Date: 2010-03-14 12:34:19 +0000 (Sun, 14 Mar 2010) $
 */
public class ComponentDefinitionRegistryImpl implements ComponentDefinitionRegistry {

    private final Map<String, ComponentMetadata> components;
    private final List<Target> typeConverters;
    private final Map<ComponentMetadata, List<Interceptor>> interceptors;

    public ComponentDefinitionRegistryImpl() {
        // Use a linked hash map to keep the declaration order 
        components = Collections.synchronizedMap(new LinkedHashMap<String, ComponentMetadata>());
        typeConverters = new CopyOnWriteArrayList<Target>();
        interceptors = Collections.synchronizedMap(new HashMap<ComponentMetadata, List<Interceptor>>());
    }

    public boolean containsComponentDefinition(String name) {
        return components.containsKey(name);
    }

    public ComponentMetadata getComponentDefinition(String name) {
        return components.get(name);
    }

    public Set<String> getComponentDefinitionNames() {
        return Collections.unmodifiableSet(components.keySet());
    }

    public void registerComponentDefinition(ComponentMetadata component) {
        String id = component.getId();
        if (id == null) {
            // TODO: should we generate a unique name?
            throw new IllegalArgumentException("Component must have a valid id");
        }
        if (id.startsWith("blueprint") && !(component instanceof PassThroughMetadataImpl)) {
            // TODO: log a warning
        }
        // TODO: perform other validation: scope, class/runtimeClass/factoryMethod, etc...
        if (components.containsKey(id)) {
            throw new ComponentNameAlreadyInUseException(id);
        }
        components.put(id, component);
    }

    public void removeComponentDefinition(String name) {
        ComponentMetadata removed = components.remove(name);
        if(removed!=null){
            interceptors.remove(removed);
        }
    }

    public void registerTypeConverter(Target component) {
        typeConverters.add(component);
        if (component instanceof ComponentMetadata) {
            registerComponentDefinition((ComponentMetadata) component);
        }
    }

    public List<Target> getTypeConverters() {
        return typeConverters;
    }

    public void registerInterceptorWithComponent(ComponentMetadata component, Interceptor interceptor) {
        if(interceptor!=null){
            List<Interceptor> componentInterceptorList = interceptors.get(component);
            if(componentInterceptorList==null){
                componentInterceptorList = new ArrayList<Interceptor>();
                interceptors.put(component, componentInterceptorList);
            }
            if(!componentInterceptorList.contains(interceptor)){
                componentInterceptorList.add(interceptor);
                Collections.sort(componentInterceptorList, new Comparator<Interceptor>(){
                    public int compare(Interceptor object1, Interceptor object2) {
                        //invert the order so higher ranks are sorted 1st
                        return object2.getRank() - object1.getRank();
                    }
                });
            }
        }
    }

    public List<Interceptor> getInterceptors(ComponentMetadata component) {
        List<Interceptor> result = interceptors.get(component);
        return (result == null) ? Collections.<Interceptor>emptyList() : result;
    }
    
}
