package org.ow2.jonas.webapp.jonasadmin.jonasmqconnect.util;

import java.lang.reflect.Method;
import java.util.ArrayList;

import javax.management.ObjectName;

import org.ow2.jonas.lib.management.extensions.base.JonasManagementRepr;


/**
 * Util class for getting MQ class properties
 *
 * @author Yacine TOUIL
 *
 */
public class PropertiesUtil {

    /**
     * Get Class Properties
     * @param mbName
     * @param mqClass
     * @param getPropertyMethodName
     * @return
     */
    public static ArrayList getClassProperties(ObjectName mbName, Class mqClass,
            String getPropertyMethodName, String serverName){
        return getClassProperties(mbName, mqClass, getPropertyMethodName, null, serverName);
    }

    /**
     * Get Class Properties
     * @param mbName
     * @param mqClass
     * @param getPropertyMethodName
     * @return
     */
    public static ArrayList getClassProperties(ObjectName mbName, Class mqClass,
            String getPropertyMethodName, String[] propertiesToRemove, String serverName){
        ArrayList properties = new ArrayList();
        Method[] mqMethod = mqClass.getMethods();
        String[] signature = new String[]{"java.lang.String"};
        Object[] params = new Object[]{};
        for (int i = 0; i < mqMethod.length; i++) {
            String propName = null;
            String propValue = null;
            try {
                String name = mqMethod[i].getName();
                if (name.startsWith("get") &&
                        mqMethod[i].getParameterTypes().length == 0 &&
                        (mqMethod[i].getReturnType().equals(String.class) ||
                        mqMethod[i].getReturnType().equals(int.class) ||
                        mqMethod[i].getReturnType().equals(Integer.class)) &&
                        !containStr(propertiesToRemove, name.substring(3))) {
                    propName = name.substring(3);
                    params = new Object[]{propName};
                    propValue = "" + JonasManagementRepr.invoke(
                            mbName, getPropertyMethodName, params, signature, serverName);
                }
            } catch (Exception ex) {
                // ignore property
                continue;
            }
            if (propName != null && propName.length() > 0) {
                properties.add(new Property(propName, propValue, propName));
            }
        }
        return properties;
    }

    /**
     * Get Properties
     * @param mbName
     * @param getPropertyMethodName
     * @param properties
     * @return
     */
    public static ArrayList getProperties(ObjectName mbName,
            String getPropertyMethodName, ArrayList propertiesName,String serverName){
        ArrayList properties = new ArrayList();
        String[] signature = new String[]{"java.lang.String"};
        Object[] params = new Object[]{};
        for (int i = 0; i < propertiesName.size(); i++) {
            String propName = null;
            String propValue = null;
            try {
                propName = (String) propertiesName.get(i);
                params = new Object[]{propName};
                propValue = "" + JonasManagementRepr.invoke(
                            mbName, getPropertyMethodName, params, signature, serverName);
            } catch (Exception ex) {
                // ignore property
                continue;
            }
            if (propName != null && propName.length() > 0) {
                properties.add(new Property(propName, propValue, propName));
            }
        }
        return properties;
    }

    /**
     * Set Class Properties
     * @param mbName
     * @param mqClass
     * @param getPropertyMethodName
     * @return
     */
    public static void setClassProperties(ObjectName mbName, /* FWA - commented out: Class mqClass, */
            String setPropertyMethodName, ArrayList properties, String serverName){
        String[] signature = new String[]{"java.lang.String",
                "java.lang.String"};
        Object[] params = new Object[]{};

        for (int i = 0; i < properties.size(); i++) {
            try {
                Property property = (Property) properties.get(i);
                String propName = property.getName();
                String propValue = property.getValue();
                params = new Object[]{propName, propValue};
                JonasManagementRepr.invoke(
                            mbName, setPropertyMethodName, params, signature, serverName);
            } catch (Exception ex) {
                LogUtils.print(ex.getMessage());
            }
        }
    }

    /**
     * Get Class Properties
     * @param mbName
     * @param mqClass
     * @param getPropertyMethodName
     * @return
     */
    public static ArrayList getJMSObjectProperties(ObjectName mbName, String selector,
            String getPropertyMethodName, String[] propertiesToRemove, String serverName, String domainName) {

        ObjectName parentConnectorON = MqObjectNames.getParentConnectorON(domainName, mbName);
        Object[] params = new String[] {
                selector };
        String[] signature = new String[]{"java.lang.String"};
        String[] propertyNames = (String[]) JonasManagementRepr.invoke(parentConnectorON, "listPropertyNames", params, signature, serverName);

        ArrayList properties = new ArrayList();
        for (int i = 0; i < propertyNames.length; i++) {
            if (!containStr(propertiesToRemove, propertyNames[i])) {

                params = new Object[]{propertyNames[i]};
                String propValue = null;
                try {
                    propValue = "" + JonasManagementRepr.invoke(
                        mbName, getPropertyMethodName, params, signature, serverName);
                } catch (Exception e) {
                    // TODO log a WARN record ? or nothing
                }
                properties.add(new Property(propertyNames[i], propValue, propertyNames[i]));
            }
        }
        return properties;
    }

    /**
     * if contain str in tab
     * @param tab
     * @param str
     * @return
     */
    private static boolean containStr(String[] tab, String str) {
        if (tab == null) {
            return false;
        }
        for (int i = 0; i < tab.length; i++) {
            if (tab[i].equals(str)) {
                return true;
            }
        }
        return false;
    }
}
