package org.jivesoftware.smackx.ikey.element;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.util.EqualsUtil;
import org.jivesoftware.smack.util.HashCode;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.ikey.util.IkeyConstants;
import org.jivesoftware.smackx.ikey.mechanism.IkeyType;

import javax.xml.namespace.QName;

public class IkeyElement implements ExtensionElement {

    public static final String NAMESPACE = IkeyConstants.NAMESPACE;
    public static final String ELEMENT = "ikey";
    public static final String ATTR_IKEY_TYPE = "type";

    @SuppressWarnings("unused")
    private static final QName QNAME = new QName(IkeyConstants.NAMESPACE, ELEMENT);

    private final IkeyType type;
    private final SuperordinateElement superordinate;
    private final SubordinateListElement subordinates;

    public IkeyElement(IkeyType type, SuperordinateElement superordinate, SubordinateListElement subordinates) {
        this.type = type;
        this.superordinate = superordinate;
        this.subordinates = subordinates;
    }

    public IkeyType getType() {
        return type;
    }

    public SuperordinateElement getSuperordinate() {
        return superordinate;
    }

    public SubordinateListElement getSubordinates() {
        return subordinates;
    }

    @Override
    public String getNamespace() {
        return NAMESPACE;
    }

    @Override
    public String getElementName() {
        return ELEMENT;
    }

    @Override
    public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) {
        return new XmlStringBuilder(this, xmlEnvironment)
                .attribute(ATTR_IKEY_TYPE, getType())
                .rightAngleBracket()
                .append(getSuperordinate())
                .append(getSubordinates())
                .closeElement(this);
    }

    @Override
    public int hashCode() {
        return HashCode.builder()
                .append(getElementName())
                .append(getType())
                .append(getSuperordinate())
                .append(getSubordinates())
                .build();
    }

    @Override
    public boolean equals(Object other) {
        return EqualsUtil.equals(this, other, (e, o) -> e
                .append(getElementName(), o.getElementName())
                .append(getType(), o.getType())
                .append(getSuperordinate(), o.getSuperordinate())
                .append(getSubordinates(), o.getSubordinates()));
    }
}
