/*
 * 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.dm.annotation.plugin.bnd;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import aQute.bnd.osgi.Annotation;

/**
 * This class encodes a component descriptor entry line, using json.
 * We are using a slightly adapted version of the nice JsonSerializingImpl class from the Apache Felix Converter project.
 * 
 * Internally, we store parameters in a map. The format of key/values stored in the map is the following:
 * 
 * The JSON object has the following form:
 * 
 * entry            ::= String | String[] | dictionary
 * dictionary       ::= key-value-pair*
 * key-value-pair   ::= key value
 * value            ::= String | String[] | value-type
 * value-type       ::= jsonObject with value-type-info
 * value-type-info  ::= "type"=primitive java type
 *                      "value"=String|String[]
 *                      
 * Exemple:
 * 
 * {"string-param" : "string-value",
 *  "string-array-param" : ["string1", "string2"],
 *  "properties" : {
 *      "string-param" : "string-value",
 *      "string-array-param" : ["str1", "str2],
 *      "long-param" : {"type":"java.lang.Long", "value":"1"}}
 *      "long-array-param" : {"type":"java.lang.Long", "value":["1"]}}
 *  }
 * }
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class EntryWriter
{
    /**
     * Every descriptor entries contains a type parameter for identifying the kind of entry
     */
    private final static String TYPE = "type";

    /** 
     * All parameters as stored in a map object 
     */
    private final HashMap<String, Object> m_params = new HashMap<>();

    /** The entry type */
    private final EntryType m_type;
    
    /**
     * Makes a new component descriptor entry.
     */
    public EntryWriter(EntryType type)
    {
        m_type = type;
        m_params.put("type", type.toString());
    }

    /**
     * Returns this entry type.
     */
    EntryType getEntryType()
    {
        return m_type;
    }

    /**
     * Returns a string representation for the given component descriptor entry.
     * @param m_logger 
     */
    public String toString()
    {
    	return new JsonWriter(m_params).toString();
    }

    /**
     * Adds a String parameter in this descritor entry.
     */
    public void put(EntryParam param, String value)
    {
        checkType(param.toString());
        m_params.put(param.toString(), value);
    }    

    /**
     * Adds a String[] parameter in this descriptor entry.
     */
    public void put(EntryParam param, String[] values)
    {
        checkType(param.toString());
        m_params.put(param.toString(), Arrays.asList(values));
    }
    
    /**
     * Adds a List of Strings in this descriptor entry.
     */
    public void put(EntryParam param, List<String> values)
    {
        checkType(param.toString());
        m_params.put(param.toString(), values);
    }

    /**
     * Returns a parameter value (either a String, or a List<String>).
     */
    public Object getParameter(EntryParam param) {
    	return m_params.get(param.toString());
    }

    /**
     * Adds a property in this descriptor entry.
     */
    @SuppressWarnings("unchecked")
    public void addProperty(String name, Object value, Class<?> type)
    {
		Map<String, Object> properties = (Map<String, Object>) m_params.get(EntryParam.properties.toString());
		if (properties == null) {
			properties = new HashMap<>();
			m_params.put(EntryParam.properties.toString(), properties);
		}
        if (value.getClass().isArray())
        {
            Object[] array = (Object[]) value;
            if (array.length == 1)
            {
                value = array[0];
            }
        }

        if (type.equals(String.class))
        {
        	properties.put(name, value.getClass().isArray() ? Arrays.asList((Object[]) value) : value);
        }
        else
        {
           Map<String, Object> val = new HashMap<>();
           val.put("type", type.getName());
           val.put("value", value.getClass().isArray() ? Arrays.asList((Object[]) value) : value);
           properties.put(name, val);
        }
    }
    
    /**
     * Get a String attribute value from an annotation and write it into this descriptor entry.
     */
    public String putString(Annotation annotation, EntryParam param, String def)
    {
        checkType(param.toString());
        Object value = annotation.get(param.toString());
        if (value == null && def != null)
        {
            value = def;
        }
        if (value != null)
        {
            put(param, value.toString());
        }
        return value == null ? null : value.toString();
    }

    /**
     * Get a class attribute value from an annotation and write it into this descriptor entry.
     */
    public void putClass(Annotation annotation, EntryParam param)
    {
        checkType(param.toString());
        String value = AnnotationCollector.parseClassAttrValue(annotation.get(param.toString()));
        if (value != null)
        {
            put(param, value);
        }
    }

    /**
     * Get a class array attribute value from an annotation and write it into this descriptor entry.
     *
     * @param annotation the annotation containing an array of classes
     * @param param the attribute name corresponding to an array of classes
     * @param def the default array of classes (String[]), if the attribute is not defined in the annotation
     * @return the class array size.
     */
    public int putClassArray(Annotation annotation, EntryParam param, Object def, Set<String> collect)
    {
        checkType(param.toString());

        boolean usingDefault = false;
        Object value = annotation.get(param.toString());
        if (value == null && def != null)
        {
            value = def;
            usingDefault = true;
        }
        if (value != null)
        {
            if (!(value instanceof Object[]))
            {
                throw new IllegalArgumentException("annotation parameter " + param
                    + " has not a class array type");
            }

            List<String> classes = new ArrayList<>();
            for (Object v: ((Object[]) value))
            {
                if (! usingDefault)
                {
                	// Parse the annotation attribute value.
                    v = AnnotationCollector.parseClassAttrValue(v);
                }
                classes.add(v.toString());
                collect.add(v.toString());
            }
            
            m_params.put(param.toString(), classes);
            return ((Object[]) value).length;
        }
        return 0;
    }

    /**
     * Check if the written key is not equals to "type" ("type" is an internal attribute we are using
     * in order to identify a kind of descriptor entry (Service, ServiceDependency, etc ...).
     */
    private void checkType(String key)
    {
        if (TYPE.equals(key))
        {
            throw new IllegalArgumentException("\"" + TYPE + "\" parameter can't be overriden");
        }
    }
}
