/*******************************************************************************
 * Copyright (c) 2009 Standard for Technology in Automotive Retail, and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * 	   David Carver (STAR) - bug 281168 - initial API and implementation
 *     David Carver  - bug 281186 - implementation of fn:id and fn:idref
 *******************************************************************************/

package org.eclipse.wst.xml.xpath2.processor.internal.function;

import org.apache.xerces.xs.ElementPSVI;
import org.apache.xerces.xs.ItemPSVI;
import org.apache.xerces.xs.XSTypeDefinition;
import org.eclipse.wst.xml.xpath2.processor.DynamicContext;
import org.eclipse.wst.xml.xpath2.processor.DynamicError;
import org.eclipse.wst.xml.xpath2.processor.ResultSequence;
import org.eclipse.wst.xml.xpath2.processor.ResultSequenceFactory;
import org.eclipse.wst.xml.xpath2.processor.internal.*;
import org.eclipse.wst.xml.xpath2.processor.internal.types.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.*;

/**
 * Returns the sequence of element nodes that have an ID value matching the value of one
 * or more of the IDREF values supplied in $arg .
 */
public class FnID extends Function {
	private static Collection _expected_args = null;
	
	/**
	 * Constructor for FnInsertBefore.
	 */
	public FnID() {
		super(new QName("id"), 1, 2);
	}

	/**
	 * Evaluate arguments.
	 * 
	 * @param args
	 *            argument expressions.
	 * @throws DynamicError
	 *             Dynamic error.
	 * @return Result of evaluation.
	 */
	@Override
	public ResultSequence evaluate(Collection args) throws DynamicError {
		return id(args, dynamic_context());
	}

	/**
	 * Insert-Before operation.
	 * 
	 * @param args
	 *            Result from the expressions evaluation.
	 * @throws DynamicError
	 *             Dynamic error.
	 * @return Result of fn:insert-before operation.
	 */
	public static ResultSequence id(Collection args, DynamicContext context) throws DynamicError {
		Collection cargs = Function.convert_arguments(args, expected_args());

		ResultSequence rs = ResultSequenceFactory.create_new();
		
		Iterator argIt = cargs.iterator();
		ResultSequence idrefRS = (ResultSequence) argIt.next();
		String[] idrefst = idrefRS.first().string_value().split(" ");

		ArrayList idrefs = createIDRefs(idrefst);
		ResultSequence nodeArg = null;
		NodeType nodeType = null;
		if (argIt.hasNext()) {
			nodeArg = (ResultSequence) argIt.next();
			nodeType = (NodeType)nodeArg.first();
		} else {
			if (context.context_item() == null) {
				throw DynamicError.contextUndefined();
			}
			if (!(context.context_item() instanceof NodeType)) {
				throw new DynamicError(TypeError.invalid_type(null));
			}
			nodeType = (NodeType) context.context_item();
			if (nodeType.node_value().getOwnerDocument() == null) {
				throw DynamicError.contextUndefined();
			}
		}
		
		Node node = nodeType.node_value();
		if (node.getOwnerDocument() == null) {
			// W3C Test suite seems to want XPDY0002
			throw DynamicError.contextUndefined();
			//throw DynamicError.noContextDoc();
		}
		
		int itemcnt = 0;
		if (hasIDREF(idrefs, node)) {
			ElementType element = new ElementType((Element) node, itemcnt);
			rs.add(element);
		}
		
		rs = processAttributes(node, idrefs, itemcnt, rs);
		rs = processChildNodes(node, idrefs, itemcnt, rs);

		return rs;
	}
	
	private static ArrayList createIDRefs(String[] idReftokens) {
		ArrayList xsidRef = new ArrayList();
		for (int i = 0; i < idReftokens.length; i++) {
			XSIDREF idref = new XSIDREF(idReftokens[i]);
			xsidRef.add(idref);
		}
		return xsidRef;
	}
	
	private static ResultSequence processChildNodes(Node node, List idrefs, int itemcnt, ResultSequence rs) {
		if (!node.hasChildNodes()) {
			return rs;
		}
		
		NodeList nodeList = node.getChildNodes();
		for (int nodecnt = 0; nodecnt < nodeList.getLength(); nodecnt++) {
			Node childNode = nodeList.item(nodecnt);
			if (childNode.getNodeType() == Node.ELEMENT_NODE && !isDuplicate(childNode, rs)) {
				ElementType element = new ElementType((Element)childNode, itemcnt);
				if (element.isID()) {
					if (hasIDREF(idrefs, childNode)) {
						itemcnt++;
						rs.add(element);
					}
				} 
				rs = processAttributes(childNode, idrefs, itemcnt, rs);
				rs = processChildNodes(childNode, idrefs, itemcnt, rs);
			}
		}
		
		return rs;

	}
	
	private static ResultSequence processAttributes(Node node, List idrefs, int itemcnt, ResultSequence rs) {
		if (!node.hasAttributes()) {
			return rs;
		}
		
		NamedNodeMap attributeList = node.getAttributes();
		for (int atsub = 0; atsub < attributeList.getLength(); atsub++) {
			Attr atNode = (Attr) attributeList.item(atsub);
			NodeType atType = new AttrType(atNode, 0);
			if (atType.isID()) {
				if (hasIDREF(idrefs, atNode)) {
					if (!isDuplicate(node, rs)) {
						ElementType element = new ElementType((Element)node, 0);
						rs.add(element);
					}
				}
			}
		}
		return rs;
	}
	
	private static boolean hasIDREF(List idrefs, Node node) {
		for (int i = 0; i < idrefs.size(); i++) {
			XSIDREF idref = (XSIDREF) idrefs.get(i);
			if (idref.string_value().equals(node.getNodeValue())) {
				return true;
			}
		}
		return false;
	}
	
	private static boolean isDuplicate(Node node, ResultSequence rs) {
		Iterator it = rs.iterator();
		while (it.hasNext()) {
			if (it.next().equals(node)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Obtain a list of expected arguments.
	 * 
	 * @return Result of operation.
	 */
	public static Collection expected_args() {
		if (_expected_args == null) {
			_expected_args = new ArrayList();
			SeqType arg = new SeqType(new XSString(), SeqType.OCC_STAR);
			_expected_args.add(arg);
			_expected_args.add(new SeqType(SeqType.OCC_NONE));
		}

		return _expected_args;
	}
	
}
