/*
 * Copyright (c) 1998, 2019 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
// mmacivor - June 24/2009 - 1.0 - Initial implementation
package org.eclipse.persistence.oxm.record;

import java.util.HashMap;
import java.util.Map;

import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.record.DomToXMLStreamWriter;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 * <p>Use this type of MarshalRecord when the marshal target is an XMLStreamWriter
 * <p><code>
 * XMLContext xmlContext = new XMLContext("session-name");<br>
 * XMLMarshaller xmlMarshaller = xmlContext.createMarshaller();<br>
 * XMLStreamWriterRecord writerRecord = new XMLStreamWriterRecord(xmlStreamWriter);<br>
 * xmlMarshaller.marshal(myObject, writerRecord);<br>
 * </code>
 * @see org.eclipse.persistence.oxm.XMLMarshaller
 */
public class XMLStreamWriterRecord extends MarshalRecord {

    private DomToXMLStreamWriter domToStreamWriter;
    private Map<String, String> prefixMapping;
    private NamespaceResolver namespaceResolver;
    private XMLStreamWriter xmlStreamWriter;

    public XMLStreamWriterRecord(XMLStreamWriter xmlStreamWriter) {
        this.xmlStreamWriter = xmlStreamWriter;
    }

    public XMLStreamWriter getXMLStreamWriter() {
        return xmlStreamWriter;
    }

    public void setXMLStreamWriter(XMLStreamWriter anXMLStreamWriter) {
        this.xmlStreamWriter = anXMLStreamWriter;
    }

    private DomToXMLStreamWriter getDomToXMLStreamWriter() {
        if(null == domToStreamWriter) {
            domToStreamWriter = new DomToXMLStreamWriter();
        }
        return domToStreamWriter;
    }

    @Override
    public void attribute(XPathFragment xPathFragment, NamespaceResolver namespaceResolver, String value) {
        try {
            String namespaceURI = xPathFragment.getNamespaceURI();
            if(namespaceURI == null) {
                xmlStreamWriter.writeAttribute(xPathFragment.getLocalName(), value);

            } else {
                String prefix = getPrefixForFragment(xPathFragment);
                if(prefix == null) {
                    xmlStreamWriter.writeAttribute(namespaceURI, xPathFragment.getLocalName(), value);
                } else {
                    xmlStreamWriter.writeAttribute(prefix, namespaceURI, xPathFragment.getLocalName(), value);
                }
            }
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void defaultNamespaceDeclaration(String defaultNamespace){
        try{
            xmlStreamWriter.writeDefaultNamespace(defaultNamespace);
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void namespaceDeclaration(String prefix, String namespaceURI){
        try{
            xmlStreamWriter.writeNamespace(prefix, namespaceURI);
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void attributeWithoutQName(String namespaceURI, String localName, String prefix, String value){
        try {
            if(namespaceURI == null || namespaceURI.length() == 0) {
                xmlStreamWriter.writeAttribute(localName, value);
            } else {
                xmlStreamWriter.writeAttribute(xmlStreamWriter.getNamespaceContext().getPrefix(namespaceURI), namespaceURI, localName, value);
            }
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void attribute(String namespaceURI, String localName, String name, String value) {
        try {
             if(namespaceURI == null || namespaceURI.length() == 0) {
                 xmlStreamWriter.writeAttribute(localName, value);
             } else {
                xmlStreamWriter.writeAttribute(xmlStreamWriter.getNamespaceContext().getPrefix(namespaceURI), namespaceURI, localName, value);
             }
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void cdata(String value) {
        try {
            for (String part : MarshalRecord.splitCData(value)) {
                xmlStreamWriter.writeCData(part);
            }
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void characters(String value) {
        try {
            xmlStreamWriter.writeCharacters(value);
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public boolean isNamespaceAware() {
        return true;
    }

    @Override
    public void closeStartElement() {
    }

    @Override
    public void openStartElement(XPathFragment xPathFragment, NamespaceResolver namespaceResolver) {
        super.openStartElement(xPathFragment, namespaceResolver);
        try {
            String namespaceURI = xPathFragment.getNamespaceURI();
            if(namespaceURI == null) {
                NamespaceContext namespaceContext = xmlStreamWriter.getNamespaceContext();
                if(null == namespaceContext) {
                    xmlStreamWriter.writeStartElement(xPathFragment.getLocalName());
                } else {
                    String defaultNamespace = namespaceContext.getNamespaceURI(Constants.EMPTY_STRING);
                    xmlStreamWriter.writeStartElement(Constants.EMPTY_STRING, xPathFragment.getLocalName(), Constants.EMPTY_STRING);
                    if(defaultNamespace != null && defaultNamespace.length() > 0 ) {
                        xmlStreamWriter.writeDefaultNamespace(Constants.EMPTY_STRING);
                    }
                }
            } else {
                String prefix = getPrefixForFragment(xPathFragment);
                if(prefix == null) {
                    prefix = Constants.EMPTY_STRING;
                }
                xmlStreamWriter.writeStartElement(prefix, xPathFragment.getLocalName(), namespaceURI);
                if(xPathFragment.isGeneratedPrefix()){
                    namespaceDeclaration(xPathFragment.getPrefix(), xPathFragment.getNamespaceURI());
                }

            }
            writePrefixMappings();
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void element(XPathFragment frag) {
        try {
            xmlStreamWriter.writeStartElement(getNameForFragment(frag));
            xmlStreamWriter.writeEndElement();
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void endDocument() {
        try {
            xmlStreamWriter.writeEndDocument();
            xmlStreamWriter.flush();
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void endElement(XPathFragment pathFragment, NamespaceResolver namespaceResolver) {
        try {
            xmlStreamWriter.writeEndElement();
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void node(Node node, NamespaceResolver resolver,String uri, String name) {
        try {
            if(node.getNodeType() == Node.DOCUMENT_NODE) {
                node = ((Document)node).getDocumentElement();
            }
            getDomToXMLStreamWriter().writeToStream(node, uri, name , this.xmlStreamWriter);
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void startDocument(String encoding, String version) {
        try {
            if(Constants.DEFAULT_XML_ENCODING.equals(encoding)) {
                xmlStreamWriter.writeStartDocument(version);
            } else {
                xmlStreamWriter.writeStartDocument(encoding, version);
            }
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void startPrefixMapping(String prefix, String namespaceUri) {
        if(null == this.prefixMapping) {
            this.prefixMapping = new HashMap<>();
        }
        this.prefixMapping.put(prefix, namespaceUri);
    }

    private void writePrefixMappings() {
        try {
            if(null != namespaceResolver) {
                String defaultNamespace = namespaceResolver.getDefaultNamespaceURI();
                if(defaultNamespace != null) {
                    xmlStreamWriter.writeNamespace(Constants.EMPTY_STRING, defaultNamespace);
                }
                if(namespaceResolver.hasPrefixesToNamespaces()) {
                    for(Map.Entry<String, String> entry:this.namespaceResolver.getPrefixesToNamespaces().entrySet()) {
                        xmlStreamWriter.writeNamespace(entry.getKey(), entry.getValue());
                    }
                }
                namespaceResolver = null;
            }
            if(null != prefixMapping) {
                for(Map.Entry<String, String> entry:this.prefixMapping.entrySet()) {
                    xmlStreamWriter.writeNamespace(entry.getKey(), entry.getValue());
                }
                prefixMapping = null;
            }
        } catch(XMLStreamException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    public void namespaceDeclarations(NamespaceResolver namespaceResolver) {
    }

    @Override
    public void startPrefixMappings(NamespaceResolver namespaceResolver) {
        this.namespaceResolver = namespaceResolver;
    }

}
