/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2011 Bull S.A.S.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 * $Id:
 * --------------------------------------------------------------------------
 */
package org.ow2.jonas.tools.maven.shade.transformers.xml;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * This class represents a XML input tag
 * @author Jeremy Cazaux
 */
public class Input implements Comparable{

    /**
     * Dom Element of an Input
     */
    Element element;

    /**
     * List of tag conditions associated
     */
    private List<Element> conditions;

    /**
     * Default constructor
     */
    public Input() {
        this.conditions = new ArrayList<Element>();
    }

    /**
     *
     * @return The list of condition Node associated to this Input
     * */
    public List<Element> getConditions() {
        return conditions;
    }

    /**
     *
     * @return  the Element of this input
     */
    public Element getElement() {
        return element;
    }

    /**
     *
     * @param element Set the element of this input
     */
    public void setElement(Element element) {
        this.element = element;
    }

    /**
     * Update conditions associated to this input
     * Update validargs attribute
     * @param conditions
     */
    public void update(final List<Element> conditions, final HashMap<String, String> properties) {

        if (conditions != null && !conditions.isEmpty()) {

            String validArgs  = this.element.getAttribute("validargs");
            String defaultValue = this.element.getAttribute("defaultvalue");
            String addProperty = this.element.getAttribute("addproperty");

            //update all condition associated to this input
            for (Element condition: conditions) {
                String arg1;
                String arg2;

                NodeList nodelist = condition.getElementsByTagName("equals");
                if (nodelist.getLength() > 0) {
                    Element equals = (Element) nodelist.item(0);
                    arg1 = equals.getAttribute("arg1");
                    arg2 = equals.getAttribute("arg2");

                    if (arg1.length() > 3) {
                        arg1 = arg1.substring(2, arg1.length() - 1);
                    }
                    if (arg2.length() > 3) {
                        arg2 = arg2.substring(2, arg2.length()-1);
                    }

                    if (arg1.equals(addProperty) && !validArgs.contains(arg2)) {
                        this.conditions.add(condition);
                    } else if (arg2.equals(addProperty) && !validArgs.contains(arg1)) {
                        this.conditions.add(condition);
                    }
                }
            }

            //initialize  valid argument of the input as a List
            List<String> validArgsList = new ArrayList<String>();
            StringTokenizer stringTokenizer = new StringTokenizer(validArgs,",");
            while (stringTokenizer.hasMoreElements()) {
                validArgsList.add(stringTokenizer.nextElement().toString());
            }

           //update validArgs list with properties hashmap
            Set keys = properties.keySet();
            Iterator it = keys.iterator();
            while (it.hasNext()){
                String key = (String) it.next();
                String values = properties.get(key);

                if (key.equals(defaultValue.substring(2, defaultValue.length() - 1))) {
                    stringTokenizer = new StringTokenizer(values, ",");
                    while (stringTokenizer.hasMoreElements()) {
                        String value = stringTokenizer.nextElement().toString();
                        if (!validArgsList.contains(value)) {
                            validArgsList.add(value);
                        }
                    }
                }
            }

            //update valid argument of this input
            StringBuffer stringBuffer = new StringBuffer();
            for (int i = 0; i < validArgsList.size(); i++) {
                stringBuffer.append(validArgsList.get(i));
                if (i < validArgsList.size() - 1) {
                    stringBuffer.append(",");
                }
            }
            this.element.setAttribute("validargs", stringBuffer.toString());
        }
    }

    /**
     * Compare two Input object
     * @param o
     * @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater
     * than the second.
     */
    public int compareTo(Object o) {
        //Inputs are sorted by their defaultValue value
        Input input = (Input) o;
        return element.getAttribute("defaultvalue").compareTo(input.getElement().getAttribute("defaultvalue"));
    }
}
