1package im.conversations.android.xmpp.model.stanza;
  2
  3import com.google.common.base.Strings;
  4import im.conversations.android.annotation.XmlElement;
  5import im.conversations.android.xmpp.model.capabilties.EntityCapabilities;
  6import im.conversations.android.xmpp.model.jabber.Show;
  7import im.conversations.android.xmpp.model.jabber.Status;
  8import java.util.Locale;
  9
 10@XmlElement
 11public class Presence extends Stanza implements EntityCapabilities {
 12
 13    public Presence() {
 14        super(Presence.class);
 15    }
 16
 17    public Presence(final Type type) {
 18        this();
 19        this.setType(type);
 20    }
 21
 22    public Availability getAvailability() {
 23        final var show = getExtension(Show.class);
 24        if (show == null) {
 25            return Availability.ONLINE;
 26        }
 27        return Availability.valueOfShown(show.getContent());
 28    }
 29
 30    public void setAvailability(final Availability availability) {
 31        if (availability == null || availability == Availability.ONLINE) {
 32            return;
 33        }
 34        this.addExtension(new Show()).setContent(availability.toShowString());
 35    }
 36
 37    public void setType(final Type type) {
 38        if (type == null) {
 39            this.removeAttribute("type");
 40        } else {
 41            this.setAttribute("type", type.toString().toLowerCase(Locale.ROOT));
 42        }
 43    }
 44
 45    public Type getType() {
 46        return Type.valueOfOrNull(this.getAttribute("type"));
 47    }
 48
 49    public void setStatus(final String status) {
 50        if (Strings.isNullOrEmpty(status)) {
 51            return;
 52        }
 53        this.addExtension(new Status()).setContent(status);
 54    }
 55
 56    public String getStatus() {
 57        final var status = getExtension(Status.class);
 58        return status == null ? null : status.getContent();
 59    }
 60
 61    public enum Type {
 62        ERROR,
 63        PROBE,
 64        SUBSCRIBE,
 65        SUBSCRIBED,
 66        UNAVAILABLE,
 67        UNSUBSCRIBE,
 68        UNSUBSCRIBED;
 69
 70        public static Type valueOfOrNull(final String type) {
 71            if (Strings.isNullOrEmpty(type)) {
 72                return null;
 73            }
 74            try {
 75                return valueOf(type.toUpperCase(Locale.ROOT));
 76            } catch (final IllegalArgumentException e) {
 77                return null;
 78            }
 79        }
 80    }
 81
 82    public enum Availability {
 83        CHAT,
 84        ONLINE,
 85        AWAY,
 86        XA,
 87        DND,
 88        OFFLINE;
 89
 90        public String toShowString() {
 91            return switch (this) {
 92                case CHAT -> "chat";
 93                case AWAY -> "away";
 94                case XA -> "xa";
 95                case DND -> "dnd";
 96                default -> null;
 97            };
 98        }
 99
100        public static Availability valueOfShown(final String content) {
101            if (Strings.isNullOrEmpty(content)) {
102                return Availability.ONLINE;
103            }
104            return switch (content) {
105                case "away" -> Availability.AWAY;
106                case "xa" -> Availability.XA;
107                case "dnd" -> Availability.DND;
108                case "chat" -> Availability.CHAT;
109                default -> Availability.ONLINE;
110            };
111        }
112    }
113}