/*
 *  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.vysper.xml.fragment;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * TODO For now, this is mostly a copy of StanzaBuilder. Both classes needs to be refactored.
 *
 * @author The Apache MINA Project (dev@mina.apache.org)
 */
@SuppressWarnings("unchecked")
public abstract class AbstractXMLElementBuilder<B extends AbstractXMLElementBuilder, T extends XMLElement> {

    class ElementStruct {
        public ElementStruct parentElement = null;
        public XMLElement element = null;
        public List<Attribute> attributes = null;
        public Map<String, String> namespaces = null;
        public List<XMLFragment> innerFragments = null;
    }

    /**
     * parent hierarchy for current element
     */
    private Stack<ElementStruct> stack = new Stack<ElementStruct>();
    protected ElementStruct currentElement = null;
    private XMLElement resultingElement = null;
    private boolean isReset = false;


    public AbstractXMLElementBuilder(String elementName) {
        this(elementName, null);
    }

    public AbstractXMLElementBuilder(String elementName, String namespaceURI) {
        this(elementName, namespaceURI, null);
    }

    public AbstractXMLElementBuilder(String elementName, String namespaceURI, String namespacePrefix) {
        startNewElement(elementName, namespaceURI, namespacePrefix);
        resultingElement = currentElement.element;
        stack.push(currentElement);
    }

    public AbstractXMLElementBuilder(String elementName, String namespaceURI, String namespacePrefix, List<Attribute> attributes, Map<String, String> namespaces, List<XMLFragment> innerFragments) {
        startNewElement(elementName, namespaceURI, namespacePrefix);
        resultingElement = currentElement.element;
        if(attributes != null) currentElement.attributes.addAll(attributes);
        if(namespaces != null) currentElement.namespaces.putAll(namespaces);
        if(innerFragments != null) currentElement.innerFragments.addAll(innerFragments);
        stack.push(currentElement);
    }
    
    protected XMLElement createElement(String namespaceURI, String name, String namespacePrefix, List<Attribute> attributes, Map<String, String> namespaces, List<XMLFragment> innerFragments) {
    	return new XMLElement(namespaceURI, name, namespacePrefix, attributes, innerFragments, namespaces);
    }
    
    private void startNewElement(String name, String namespaceURI, String namespacePrefix) {
        // TODO assert that name does not contain namespace (":")
        // TODO handle the namespace, given by URI, currently always NULL in XMLElement constructors
        ElementStruct element = new ElementStruct();
        element.attributes = new ArrayList<Attribute>();
        element.namespaces = new HashMap<String, String>();
        element.innerFragments = new ArrayList<XMLFragment>();
        element.element = createElement(namespaceURI, name, namespacePrefix, element.attributes, element.namespaces, element.innerFragments);

        currentElement = element;
    }
    
    public B declareNamespace(String namespacePrefix, String value) {
        currentElement.namespaces.put(namespacePrefix, value);
        return (B) this;
    }

    public B addAttribute(String name, String value) {
    	addAttribute(new Attribute(name, value));
    	return (B) this;
    }

    public B addAttribute(String namespaceUris, String name, String value) {
    	addAttribute(new Attribute(namespaceUris, name, value));
    	return (B) this;
    }

    
    public B addAttribute(Attribute attribute) {
        checkReset();
        currentElement.attributes.add(attribute);
        return (B) this;
    }

    public B addText(String text) {
        checkReset();
        currentElement.innerFragments.add(new XMLText(text));
        return (B) this;
    }

    public B startInnerElement(String name) {
        return this.startInnerElement(name, null);
    }

    public B startInnerElement(String name, String namespaceURI) {
        checkReset();

        startNewElement(name, namespaceURI, null);

        stack.peek().innerFragments.add(currentElement.element); // add new one to its parent

        stack.push(currentElement);

        return (B) this;
    }

    public B endInnerElement() {
        checkReset();
        if (stack.isEmpty()) throw new IllegalStateException("cannot end beyond top element");

        stack.pop(); // take current off stack and forget (it was added to its parent before)
        currentElement = stack.peek(); // we again deal with parent, which can be receive additions
        return (B) this;
    }

    public B addPreparedElement(XMLElement preparedElement) {
        checkReset();
        currentElement.innerFragments.add(preparedElement);
        return (B) this;
    }

    /**
     * the stanza can only be retrieved once
     * @return retrieves the XML element and invalidates the builder
     */
    public T build() {
        checkReset();
        XMLElement returnStanza = resultingElement;
        resultingElement = null;
        isReset = true; // reset
        stack.clear();
        return (T) returnStanza;
    }

    /**
     * assure that the immutable XML element object is not changed after it was retrieved
     */
    private void checkReset() {
        if (isReset) throw new IllegalStateException("XML element builder was reset after retrieving stanza");
    }
}
