package org.xbib.io.webdav.client;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xbib.io.webdav.api.DavConstants;
import org.xbib.io.webdav.api.XMLizable;
import org.xbib.io.webdav.common.DavPropertyNameSet;
import org.xbib.io.webdav.common.DomUtil;

public class PropfindInfo implements XMLizable {

    private final int propfindType;
    private final DavPropertyNameSet propNameSet;

    public PropfindInfo(int propfindType, DavPropertyNameSet propNameSet) {
        this.propfindType = propfindType;
        this.propNameSet = propNameSet;
    }

    @Override
    public Element toXml(Document document) {
        Element propfind = DomUtil.createElement(document, DavConstants.XML_PROPFIND, DavConstants.NAMESPACE);

        // fill the propfind element
        switch (propfindType) {
            case DavConstants.PROPFIND_ALL_PROP:
                propfind.appendChild(DomUtil.createElement(document, DavConstants.XML_ALLPROP, DavConstants.NAMESPACE));
                break;

            case DavConstants.PROPFIND_PROPERTY_NAMES:
                propfind.appendChild(DomUtil.createElement(document, DavConstants.XML_PROPNAME, DavConstants.NAMESPACE));
                break;

            case DavConstants.PROPFIND_BY_PROPERTY:
                if (propNameSet == null) {
                    // name set missing, ask for a property that is known to
                    // exist
                    Element prop = DomUtil.createElement(document, DavConstants.XML_PROP, DavConstants.NAMESPACE);
                    Element resourcetype = DomUtil.createElement(document, DavConstants.PROPERTY_RESOURCETYPE,
                            DavConstants.NAMESPACE);
                    prop.appendChild(resourcetype);
                    propfind.appendChild(prop);
                } else {
                    propfind.appendChild(propNameSet.toXml(document));
                }
                break;

            case DavConstants.PROPFIND_ALL_PROP_INCLUDE:
                propfind.appendChild(DomUtil.createElement(document, DavConstants.XML_ALLPROP, DavConstants.NAMESPACE));
                if (propNameSet != null && !propNameSet.isEmpty()) {
                    Element include = DomUtil.createElement(document, DavConstants.XML_INCLUDE, DavConstants.NAMESPACE);
                    Element prop = propNameSet.toXml(document);
                    for (Node c = prop.getFirstChild(); c != null; c = c.getNextSibling()) {
                        // copy over the children of <prop> to <include>
                        // element
                        include.appendChild(c.cloneNode(true));
                    }
                    propfind.appendChild(include);
                }
                break;

            default:
                throw new IllegalArgumentException("unknown propfind type");
        }

        return propfind;
    }
}
