/*
 * 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.webconsole.plugins.memoryusage.internal;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;

import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.metatype.AttributeDefinition;
import org.osgi.service.metatype.MetaTypeProvider;
import org.osgi.service.metatype.ObjectClassDefinition;

class MemoryUsageConfigurator implements ManagedService, MetaTypeProvider
{

    private final MemoryUsageSupport support;

    private ObjectClassDefinition ocd;

    MemoryUsageConfigurator(final MemoryUsageSupport support)
    {
        this.support = support;
    }

    @SuppressWarnings("unchecked")
    public void updated(Dictionary properties) throws ConfigurationException
    {
        // ensure default values if there is no config or config is deleted
        if (properties == null)
        {
            properties = new Hashtable();
        }

        final Object thresholdValue = properties.get(MemoryUsageConstants.PROP_DUMP_THRESHOLD);
        if (thresholdValue != null)
        {
            final int threshold;
            if (thresholdValue instanceof Number)
            {
                threshold = ((Number) thresholdValue).intValue();
            }
            else
            {
                // try to convert
                try
                {
                    threshold = Integer.parseInt(thresholdValue.toString());
                }
                catch (NumberFormatException nfe)
                {
                    throw thresholdFailure(thresholdValue);
                }
            }

            try
            {
                support.setThreshold(threshold);
            }
            catch (IllegalArgumentException iae)
            {
                throw thresholdFailure(iae.getMessage());
            }
        }
        else
        {
            support.setThreshold(-1);
        }

        final Object intervalValue = properties.get(MemoryUsageConstants.PROP_DUMP_INTERVAL);
        if (intervalValue != null)
        {
            final int interval;
            if (intervalValue instanceof Number)
            {
                interval = ((Number) intervalValue).intValue();
            }
            else
            {
                // try to convert
                try
                {
                    interval = Integer.parseInt(intervalValue.toString());
                }
                catch (NumberFormatException nfe)
                {
                    throw intervalFailure(intervalValue);
                }
            }

            try
            {
                support.setInterval(interval);
            }
            catch (IllegalArgumentException iae)
            {
                throw intervalFailure(iae.getMessage());
            }
        }
        else
        {
            support.setInterval(-1);
        }

        final Object locationValue = properties.get(MemoryUsageConstants.PROP_DUMP_LOCATION);
        if (locationValue instanceof String)
        {
            support.setDumpLocation((String) locationValue);
        }
        else
        {
            support.setDumpLocation(null);
        }
    }

    public String[] getLocales()
    {
        return null;
    }

    public ObjectClassDefinition getObjectClassDefinition(String id, String locale)
    {
        if (!MemoryUsageConstants.PID.equals(id))
        {
            return null;
        }

        if (ocd == null)
        {

            final ArrayList<AttributeDefinition> adList = new ArrayList<AttributeDefinition>();

            adList.add(new AttributeDefinitionImpl(MemoryUsageConstants.PROP_DUMP_THRESHOLD, "Dump Threshold",
                "Threshold at which to automatically create a memory dump as a percentage in the range "
                + MemoryUsageConstants.MIN_DUMP_THRESHOLD + " to " + MemoryUsageConstants.MAX_DUMP_THRESHOLD
                + " or zero to disable automatic dump creation.", AttributeDefinition.INTEGER, new String[]
                                                                                                          { String.valueOf(MemoryUsageConstants.DEFAULT_DUMP_THRESHOLD) }, 0, null, null)
            {
                @Override
                public String validate(String value)
                {
                    try
                    {
                        int threshold = Integer.parseInt(value);
                        if (!MemoryUsageConstants.isThresholdValid(threshold))
                        {
                            return "Dump Threshold must in the range " + MemoryUsageConstants.MIN_DUMP_THRESHOLD
                                + " to " + MemoryUsageConstants.MAX_DUMP_THRESHOLD + " or zero";
                        }
                        return ""; // everything ok
                    }
                    catch (NumberFormatException nfe)
                    {
                        return "Dump Threshhold must be numeric";
                    }
                }
            });

            adList.add(new AttributeDefinitionImpl(MemoryUsageConstants.PROP_DUMP_INTERVAL, "Dump Interval",
                "The minimum interval between two consecutive memory dumps being taken in seconds. "
                    + "This property allows the limitation of the number of memory dumps being taken. "
                    + "The default value for the interval is 6 hours. This means that a memory threshold "
                    + "event is ignored unless the last memory dump has been taken at least 6 hours earlier. "
                    + "This property allows limiting the number of memory dumps in case memory consumption is "
                    + "oscillating around the threshold point. The property must be an integer value or be "
                    + "parseable to an integer value. This should be a positive value or zero to force each "
                    + "memory threshold event to cause a memory dump (discouraged).", AttributeDefinition.INTEGER,
                new String[]
                    { String.valueOf(MemoryUsageConstants.DEFAULT_DUMP_INTERVAL) }, 0, null, null)
            {
                @Override
                public String validate(String value)
                {
                    try
                    {
                        int interval = Integer.parseInt(value);
                        if (interval < 0)
                        {
                            return "Dump Interval must be zero or a positive number";
                        }
                        return ""; // everything ok
                    }
                    catch (NumberFormatException nfe)
                    {
                        return "Dump Interval must be numeric";
                    }
                }
            });

            adList.add(new AttributeDefinitionImpl(MemoryUsageConstants.PROP_DUMP_LOCATION, "Dumpe Location",
                "The filesystem location where heap dumps are stored. If this is null or empty (the default) the dumps are stored in "
                    + support.getDefaultDumpLocation(), ""));

            ocd = new ObjectClassDefinition()
            {

                private final AttributeDefinition[] attrs = adList.toArray(new AttributeDefinition[adList.size()]);

                public String getName()
                {
                    return "Apache Felix Web Console Memory Usage Plugin";
                }

                public InputStream getIcon(int arg0)
                {
                    return null;
                }

                public String getID()
                {
                    return MemoryUsageConstants.PID;
                }

                public String getDescription()
                {
                    return "Configuration of the Apache Felix Web Console Memory Usage Plugin.";
                }

                public AttributeDefinition[] getAttributeDefinitions(int filter)
                {
                    return (filter == OPTIONAL) ? null : attrs;
                }
            };
        }

        return ocd;
    }

    private ConfigurationException thresholdFailure(final Object invalidValue)
    {
        return new ConfigurationException(MemoryUsageConstants.PROP_DUMP_THRESHOLD, "Invalid Dump Threshold value '"
            + invalidValue + "': Must be an integer number in the range " + MemoryUsageConstants.MIN_DUMP_THRESHOLD
            + " to " + MemoryUsageConstants.MAX_DUMP_THRESHOLD + " or zero to disable");
    }

    private ConfigurationException intervalFailure(final Object invalidValue)
    {
        return new ConfigurationException(MemoryUsageConstants.PROP_DUMP_INTERVAL, "Invalid Dump Interval value '"
            + invalidValue + "': Must be a positive integer number or zero to disable");
    }

    private static class AttributeDefinitionImpl implements AttributeDefinition
    {

        private final String id;
        private final String name;
        private final String description;
        private final int type;
        private final String[] defaultValues;
        private final int cardinality;
        private final String[] optionLabels;
        private final String[] optionValues;

        AttributeDefinitionImpl(final String id, final String name, final String description, final String defaultValue)
        {
            this(id, name, description, STRING, new String[]
                { defaultValue }, 0, null, null);
        }

        AttributeDefinitionImpl(final String id, final String name, final String description, final int type,
            final String[] defaultValues, final int cardinality, final String[] optionLabels,
            final String[] optionValues)
        {
            this.id = id;
            this.name = name;
            this.description = description;
            this.type = type;
            this.defaultValues = defaultValues;
            this.cardinality = cardinality;
            this.optionLabels = optionLabels;
            this.optionValues = optionValues;
        }

        public int getCardinality()
        {
            return cardinality;
        }

        public String[] getDefaultValue()
        {
            return defaultValues;
        }

        public String getDescription()
        {
            return description;
        }

        public String getID()
        {
            return id;
        }

        public String getName()
        {
            return name;
        }

        public String[] getOptionLabels()
        {
            return optionLabels;
        }

        public String[] getOptionValues()
        {
            return optionValues;
        }

        public int getType()
        {
            return type;
        }

        public String validate(String arg0)
        {
            return null;
        }
    }
}
