/*******************************************************************************
 * Copyright (c) 2017 École Polytechnique de Montréal
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License 2.0 which
 * accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/

package org.eclipse.tracecompass.tmf.analysis.xml.core.module;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * Class containing some utilities methods that can be used by analyses
 * extending the XML schema
 *
 * @author Geneviève Bastien
 * @since 2.2
 */
public final class TmfXmlUtils {

    private TmfXmlUtils() {

    }

    /**
     * Get the XML children element of an XML element, but only those of a
     * certain type
     *
     * @param parent
     *            The parent element to get the children from
     * @param elementTag
     *            The tag of the elements to return
     * @return The list of children {@link Element} of the parent
     */
    public static @NonNull List<@NonNull Element> getChildElements(Element parent, String elementTag) {
        /* get the state providers and find the corresponding one */
        NodeList nodes = parent.getElementsByTagName(elementTag);
        List<@NonNull Element> childElements = new ArrayList<>();

        for (int i = 0; i < nodes.getLength(); i++) {
            Element node = (Element) nodes.item(i);
            if (node.getParentNode().equals(parent)) {
                childElements.add(node);
            }
        }
        return childElements;
    }

    /**
     * Return the node element corresponding to the requested type in the file.
     *
     * TODO: Nothing prevents from having duplicate type -> id in a same file.
     * That should not be allowed. If you want an element with the same ID as
     * another one, it should be in a different file and we should check it at
     * validation time.
     *
     * @param filePath
     *            The absolute path to the XML file
     * @param elementType
     *            The type of top level element to search for
     * @param elementId
     *            The ID of the desired element
     * @return The XML element or <code>null</code> if not found
     */
    public static Element getElementInFile(String filePath, @NonNull String elementType, @NonNull String elementId) {

        if (filePath == null) {
            return null;
        }

        IPath path = new Path(filePath);
        File file = path.toFile();
        if (file == null || !file.exists() || !file.isFile() || !XmlUtils.xmlValidate(file).isOK()) {
            return null;
        }

        try {
            Document doc = XmlUtils.getDocumentFromFile(file);

            /* get the state providers and find the corresponding one */
            NodeList nodes = doc.getElementsByTagName(elementType);
            Element foundNode = null;

            for (int i = 0; i < nodes.getLength(); i++) {
                Element node = (Element) nodes.item(i);
                String id = node.getAttribute(TmfXmlStrings.ID);
                if (id.equals(elementId)) {
                    foundNode = node;
                }
            }
            return foundNode;
        } catch (ParserConfigurationException | SAXException | IOException e) {
            return null;
        }

    }

    /**
     * Return the ITmfStateValue.Type corresponding to the given type name.
     *
     * @param typeName
     *              The ITmfStateValue.Type name.
     *
     * @return The ITmfStateValue.Type
     * @since 2.3
     */
     public static ITmfStateValue.@Nullable Type getTmfStateValueByName(@NonNull String typeName){

        ITmfStateValue.Type type;
        switch (typeName) {
        case TmfXmlStrings.TYPE_STRING:
            type = ITmfStateValue.Type.STRING;
            break;
        case TmfXmlStrings.TYPE_INT:
            type = ITmfStateValue.Type.INTEGER;
            break;
        case TmfXmlStrings.TYPE_LONG:
            type = ITmfStateValue.Type.LONG;
            break;
        case TmfXmlStrings.TYPE_DOUBLE:
            type = ITmfStateValue.Type.DOUBLE;
            break;
        case TmfXmlStrings.TYPE_CUSTOM:
            type = ITmfStateValue.Type.CUSTOM;
            break;
        case TmfXmlStrings.TYPE_NULL:
            type = ITmfStateValue.Type.NULL;
            break;
        default:
            return null;
        }
        return type;
    }

     /**
      * Factory constructor for Object state values
      *
      * @param objValue
      *            The object value to contain
      * @return The newly-created TmfStateValue object
      * @since 2.3
      */
    public static @NonNull TmfStateValue newTmfStateValueFromObject(@Nullable Object objValue) {
        TmfStateValue value = TmfStateValue.nullValue();
        if (objValue instanceof String) {
            value = TmfStateValue.newValueString((String) objValue);
        } else if (objValue instanceof Long) {
            value = TmfStateValue.newValueLong((Long) objValue);
        } else if (objValue instanceof Integer) {
            value = TmfStateValue.newValueInt((Integer) objValue);
        } else if (objValue instanceof Double) {
            value = TmfStateValue.newValueDouble((Double) objValue);
        }
        return value;
    }

    /**
     * Factory constructor for Object state values with a forced type.
     *
     * @param objValue
     *            The object value to contain
     * @param forcedType
     *            The forced type
     * @return The newly-created TmfStateValue object
     * @since 2.3
     */
    public static @NonNull TmfStateValue newTmfStateValueFromObjectWithForcedType(@Nullable Object objValue, ITmfStateValue.@NonNull Type forcedType) {
        if (objValue == null) {
            return TmfStateValue.nullValue();
        }
        TmfStateValue value = TmfStateValue.nullValue();
        if (objValue instanceof String) {
            String fieldString = (String) objValue;
            switch (forcedType) {
            case INTEGER:
                value = TmfStateValue.newValueInt(Integer.parseInt(fieldString));
                break;
            case LONG:
                value = TmfStateValue.newValueLong(Long.parseLong(fieldString));
                break;
            case DOUBLE:
                value = TmfStateValue.newValueDouble(Double.parseDouble(fieldString));
                break;
            case CUSTOM:
                throw new IllegalStateException("Custom type cannot be forced"); //$NON-NLS-1$
            case STRING:
            case NULL:
            default:
                value = TmfStateValue.newValueString(fieldString);
                break;
            }
        } else if (objValue instanceof Long) {
            Long fieldLong = (Long) objValue;
            switch (forcedType) {
            case INTEGER:
                value = TmfStateValue.newValueInt(fieldLong.intValue());
                break;
            case STRING:
                value = TmfStateValue.newValueString(fieldLong.toString());
                break;
            case DOUBLE:
                value = TmfStateValue.newValueDouble(fieldLong.doubleValue());
                break;
            case CUSTOM:
                throw new IllegalStateException("Custom type cannot be forced"); //$NON-NLS-1$
            case LONG:
            case NULL:
            default:
                value = TmfStateValue.newValueLong(fieldLong);
                break;
            }
        } else if (objValue instanceof Integer) {
            Integer fieldInteger = (Integer) objValue;
            switch (forcedType) {
            case LONG:
                value = TmfStateValue.newValueLong(fieldInteger.longValue());
                break;
            case STRING:
                value = TmfStateValue.newValueString(fieldInteger.toString());
                break;
            case DOUBLE:
                value = TmfStateValue.newValueDouble(fieldInteger.doubleValue());
                break;
            case CUSTOM:
                throw new IllegalStateException("Custom type cannot be forced"); //$NON-NLS-1$
            case INTEGER:
            case NULL:
            default:
                value = TmfStateValue.newValueInt(fieldInteger);
                break;
            }
        } else if (objValue instanceof Double) {
            Double fieldDouble = (Double) objValue;
            switch (forcedType) {
            case LONG:
                value = TmfStateValue.newValueLong(fieldDouble.longValue());
                break;
            case STRING:
                value = TmfStateValue.newValueString(fieldDouble.toString());
                break;
            case INTEGER:
                value = TmfStateValue.newValueInt(fieldDouble.intValue());
                break;
            case CUSTOM:
                throw new IllegalStateException("Custom type cannot be forced"); //$NON-NLS-1$
            case DOUBLE:
            case NULL:
            default:
                value = TmfStateValue.newValueDouble(fieldDouble);
                break;
            }
        } else {
            value = TmfStateValue.newValueString(objValue.toString());
        }
        return value;
    }

    /**
     * Get the list of analysis IDs this view is for, as listed in the header of
     * the XML element
     *
     * @param viewElement
     *            The XML view element from which to get the analysis IDs
     * @return The list of all analysis IDs this view is for
     * @since 2.4
     */
    public static @NonNull Set<@NonNull String> getViewAnalysisIds(Element viewElement) {
        List<Element> heads = getChildElements(viewElement, TmfXmlStrings.HEAD);

        Set<@NonNull String> analysisIds = new HashSet<>();
        if (!heads.isEmpty()) {
            Element head = heads.get(0);

            /* Get the application analysis from the view's XML header */
            List<Element> applicableAnalysis = getChildElements(head, TmfXmlStrings.ANALYSIS);
            for (Element oneAnalysis : applicableAnalysis) {
                analysisIds.add(oneAnalysis.getAttribute(TmfXmlStrings.ID));
            }
        }
        return analysisIds;
    }
}
