/*
 * Decompiled with CFR 0.152.
 */
package org.jivesoftware.smack.packet;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.jivesoftware.smack.packet.AbstractError;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;

public class XMPPError
extends AbstractError {
    public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-stanzas";
    public static final String ERROR = "error";
    private static final Logger LOGGER = Logger.getLogger(XMPPError.class.getName());
    private static final Map<Condition, Type> CONDITION_TO_TYPE = new HashMap<Condition, Type>();
    private final Condition condition;
    private final String conditionText;
    private final String errorGenerator;
    private final Type type;

    public XMPPError(Condition condition) {
        this(condition, null, null, null, null, null);
    }

    public XMPPError(Condition condition, ExtensionElement applicationSpecificCondition) {
        this(condition, null, null, null, null, Arrays.asList(applicationSpecificCondition));
    }

    public XMPPError(Condition condition, String conditionText, String errorGenerator, Type type, Map<String, String> descriptiveTexts, List<ExtensionElement> extensions) {
        super(descriptiveTexts, NAMESPACE, extensions);
        this.condition = condition;
        if (StringUtils.isNullOrEmpty(conditionText)) {
            conditionText = null;
        }
        if (conditionText != null) {
            switch (condition) {
                case gone: 
                case redirect: {
                    break;
                }
                default: {
                    throw new IllegalArgumentException("Condition text can only be set with condtion types 'gone' and 'redirect', not " + (Object)((Object)condition));
                }
            }
        }
        this.conditionText = conditionText;
        this.errorGenerator = errorGenerator;
        if (type == null) {
            Type determinedType = CONDITION_TO_TYPE.get((Object)condition);
            if (determinedType == null) {
                LOGGER.warning("Could not determine type for condition: " + (Object)((Object)condition));
                determinedType = Type.CANCEL;
            }
            this.type = determinedType;
        } else {
            this.type = type;
        }
    }

    public Condition getCondition() {
        return this.condition;
    }

    public Type getType() {
        return this.type;
    }

    public String getErrorGenerator() {
        return this.errorGenerator;
    }

    public String getConditionText() {
        return this.conditionText;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder("XMPPError: ");
        sb.append(this.condition.toString()).append(" - ").append(this.type.toString());
        if (this.errorGenerator != null) {
            sb.append(". Generated by ").append(this.errorGenerator);
        }
        return sb.toString();
    }

    public XmlStringBuilder toXML() {
        XmlStringBuilder xml = new XmlStringBuilder();
        xml.halfOpenElement(ERROR);
        xml.attribute("type", this.type.toString());
        xml.optAttribute("by", this.errorGenerator);
        xml.rightAngleBracket();
        xml.halfOpenElement(this.condition.toString());
        xml.xmlnsAttribute(NAMESPACE);
        if (this.conditionText != null) {
            xml.rightAngleBracket();
            xml.escape(this.conditionText);
            xml.closeElement(this.condition.toString());
        } else {
            xml.closeEmptyElement();
        }
        this.addDescriptiveTextsAndExtensions(xml);
        xml.closeElement(ERROR);
        return xml;
    }

    public static XMPPError from(Condition condition, String descriptiveText) {
        HashMap<String, String> descriptiveTexts = new HashMap<String, String>();
        descriptiveTexts.put("en", descriptiveText);
        return new XMPPError(condition, null, null, null, descriptiveTexts, null);
    }

    static {
        CONDITION_TO_TYPE.put(Condition.bad_request, Type.MODIFY);
        CONDITION_TO_TYPE.put(Condition.conflict, Type.CANCEL);
        CONDITION_TO_TYPE.put(Condition.feature_not_implemented, Type.CANCEL);
        CONDITION_TO_TYPE.put(Condition.forbidden, Type.AUTH);
        CONDITION_TO_TYPE.put(Condition.gone, Type.CANCEL);
        CONDITION_TO_TYPE.put(Condition.internal_server_error, Type.CANCEL);
        CONDITION_TO_TYPE.put(Condition.item_not_found, Type.CANCEL);
        CONDITION_TO_TYPE.put(Condition.jid_malformed, Type.MODIFY);
        CONDITION_TO_TYPE.put(Condition.not_acceptable, Type.MODIFY);
        CONDITION_TO_TYPE.put(Condition.not_allowed, Type.CANCEL);
        CONDITION_TO_TYPE.put(Condition.not_authorized, Type.AUTH);
        CONDITION_TO_TYPE.put(Condition.policy_violation, Type.MODIFY);
        CONDITION_TO_TYPE.put(Condition.recipient_unavailable, Type.WAIT);
        CONDITION_TO_TYPE.put(Condition.redirect, Type.MODIFY);
        CONDITION_TO_TYPE.put(Condition.registration_required, Type.AUTH);
        CONDITION_TO_TYPE.put(Condition.remote_server_not_found, Type.CANCEL);
        CONDITION_TO_TYPE.put(Condition.remote_server_timeout, Type.WAIT);
        CONDITION_TO_TYPE.put(Condition.resource_constraint, Type.WAIT);
        CONDITION_TO_TYPE.put(Condition.service_unavailable, Type.WAIT);
        CONDITION_TO_TYPE.put(Condition.subscription_required, Type.WAIT);
        CONDITION_TO_TYPE.put(Condition.unexpected_request, Type.MODIFY);
    }

    public static enum Condition {
        bad_request,
        conflict,
        feature_not_implemented,
        forbidden,
        gone,
        internal_server_error,
        item_not_found,
        jid_malformed,
        not_acceptable,
        not_allowed,
        not_authorized,
        policy_violation,
        recipient_unavailable,
        redirect,
        registration_required,
        remote_server_not_found,
        remote_server_timeout,
        resource_constraint,
        service_unavailable,
        subscription_required,
        undefined_condition,
        unexpected_request;


        public String toString() {
            return this.name().replace('_', '-');
        }

        public static Condition fromString(String string) {
            if ("xml-not-well-formed".equals(string)) {
                string = "not-well-formed";
            }
            string = string.replace('-', '_');
            Condition condition = null;
            try {
                condition = Condition.valueOf(string);
            }
            catch (Exception e) {
                throw new IllegalStateException("Could not transform string '" + string + "' to XMPPErrorCondition", e);
            }
            return condition;
        }
    }

    public static enum Type {
        WAIT,
        CANCEL,
        MODIFY,
        AUTH,
        CONTINUE;


        public String toString() {
            return this.name().toLowerCase();
        }

        public static Type fromString(String string) {
            string = string.toUpperCase();
            return Type.valueOf(string);
        }
    }
}
