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

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Hashtable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.aries.blueprint.utils.ReflectionUtils;
import org.osgi.service.blueprint.container.ComponentDefinitionException;

/**
 * @version $Rev: 896324 $ $Date: 2010-01-06 06:05:04 +0000 (Wed, 06 Jan 2010) $
 */
public class MapRecipe extends AbstractRecipe {

    private final List<Recipe[]> entries;
    private final Class typeClass;

    public MapRecipe(String name, Class type) {
        super(name);
        if (type == null) throw new NullPointerException("type is null");
        this.typeClass = type;
        this.entries = new ArrayList<Recipe[]>();
    }

    public List<Recipe> getDependencies() {
        List<Recipe> nestedRecipes = new ArrayList<Recipe>(entries.size() * 2);
        for (Recipe[] entry : entries) {
            nestedRecipes.add(entry[0]);
            if (entry[1] != null) {
                nestedRecipes.add(entry[1]);
            }
        }
        return nestedRecipes;
    }

    protected Object internalCreate() throws ComponentDefinitionException {
        Class mapType = getMap(typeClass);

        if (!ReflectionUtils.hasDefaultConstructor(mapType)) {
            throw new ComponentDefinitionException("Type does not have a default constructor " + mapType.getName());
        }

        Object o;
        try {
            o = mapType.newInstance();
        } catch (Exception e) {
            throw new ComponentDefinitionException("Error while creating set instance: " + mapType.getName());
        }

        Map instance;
        if (o instanceof Map) {
            instance = (Map) o;
        } else if (o instanceof Dictionary) {
            instance = new DummyDictionaryAsMap((Dictionary) o);
        } else {
            throw new ComponentDefinitionException("Specified map type does not implement the Map interface: " + mapType.getName());
        }

        // add map entries
        for (Recipe[] entry : entries) {
            Object key = entry[0].create();
            Object value = entry[1] != null ? entry[1].create() : null;
            instance.put(key, value);
        }
        return instance;
    }

    public void put(Recipe key, Recipe value) {
        if (key == null) throw new NullPointerException("key is null");
        entries.add(new Recipe[] { key, value});
    }

    public void putAll(Map<Recipe,Recipe> map) {
        if (map == null) throw new NullPointerException("map is null");
        for (Map.Entry<Recipe,Recipe> entry : map.entrySet()) {
            Recipe key = entry.getKey();
            Recipe value = entry.getValue();
            put(key, value);
        }
    }

    public static Class getMap(Class type) {
        if (ReflectionUtils.hasDefaultConstructor(type)) {
            return type;
        } else if (SortedMap.class.isAssignableFrom(type)) {
            return TreeMap.class;
        } else if (ConcurrentMap.class.isAssignableFrom(type)) {
            return ConcurrentHashMap.class;
        } else {
            return LinkedHashMap.class;
        }
    }

    public static class DummyDictionaryAsMap extends AbstractMap {

        private final Dictionary dictionary;

        public DummyDictionaryAsMap(Dictionary dictionary) {
            this.dictionary = dictionary;
        }

        @Override
        public Object put(Object key, Object value) {
            return dictionary.put(key, value);
        }

        public Set entrySet() {
            throw new UnsupportedOperationException();
        }
    }

}
