/*
 * 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.testing.mock.osgi;

import java.util.Arrays;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Map util methods.
 */
public final class MapUtil {
    
    private MapUtil() {
        // static methods only
    }

    /**
     * Convert map to dictionary.
     * @param <T> Key
     * @param <U> Value
     * @param map Map
     * @return Dictionary
     */
    public static @Nullable <T, U> Dictionary<T, U> toDictionary(@Nullable Map<T, U> map) {
        if (map == null) {
            return null;
        }
        Hashtable<T, U> hashtable = new Hashtable<>();
        for (Map.Entry<T, U> entry : map.entrySet()) {
            if (entry.getKey() != null && entry.getValue() != null) {
                hashtable.put(entry.getKey(), entry.getValue());
            }
        }
        return hashtable;
    }

    /**
     * Convert Dictionary to map
     * @param <T> Key
     * @param <U> Value
     * @param dictionary Dictionary
     * @return Map
     */
    public static @Nullable <T, U> Map<T, U> toMap(@Nullable Dictionary<T, U> dictionary) {
        if (dictionary == null) {
            return null;
        }
        Map<T, U> map = new HashMap<T, U>();
        Enumeration<T> keys = dictionary.keys();
        while (keys.hasMoreElements()) {
            T key = keys.nextElement();
            map.put(key, dictionary.get(key));
        }
        return map;
    }

    /**
     * Convert key/value pairs to dictionary
     * @param args Key/value pairs
     * @return Dictionary
     */
    public static @Nullable Dictionary<String, Object> toDictionary(@NotNull Object... args) {
        return toDictionary(toMap(args));
    }
    
    /**
     * Convert key/value pairs to map
     * @param args Key/value pairs
     * @return Map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> toMap(@NotNull Object... args) {
        if (args == null || args.length == 0) {
            return Collections.emptyMap();
        }
        if (args.length == 1) {
            if (args[0] instanceof Map) {
                return (Map)args[0];
            }
            else if (args[0] instanceof Dictionary) {
                return toMap((Dictionary)args[0]);
            }
        }
        if (args.length % 2 != 0) {
            throw new IllegalArgumentException("args must be an even number of name/values:" + Arrays.asList(args));
        }
        final Map<String, Object> result = new HashMap<>();
        for (int i=0 ; i < args.length; i+=2) {
            Object key = args[i];
            Object value = args[i+1];
            if (key != null && value != null) {
                result.put(key.toString(), value);
            }
        }
        return result;
    }
    
}
