package org.jxmpp.jid.impl;

import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.DomainFullJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.JidWithLocalpart;
import org.jxmpp.jid.JidWithResource;
import org.jxmpp.jid.parts.Localpart;
import org.jxmpp.jid.parts.Resourcepart;

public abstract class AbstractJid implements Jid {
   public final boolean isBareOrFullJid() {
      return this.isBareJid() || this.isFullJid();
   }

   public final boolean isBareJid() {
      return this instanceof BareJid;
   }

   public final boolean isFullJid() {
      return this instanceof FullJid;
   }

   public final boolean isDomainBareJid() {
      return this instanceof DomainBareJid;
   }

   public final boolean isDomainFullJid() {
      return this instanceof DomainFullJid;
   }

   public abstract boolean hasNoResource();

   public final boolean hasResource() {
      return this instanceof JidWithResource;
   }

   public final boolean hasLocalpart() {
      return this instanceof JidWithLocalpart;
   }

   public final <T extends Jid> T downcast() {
      return this;
   }

   public int length() {
      return this.toString().length();
   }

   public char charAt(int index) {
      return this.toString().charAt(index);
   }

   public CharSequence subSequence(int start, int end) {
      return this.toString().subSequence(start, end);
   }

   public Resourcepart getResourceOrNull() {
      return null;
   }

   public Localpart getLocalpartOrNull() {
      return null;
   }

   public final boolean isParentOf(Jid jid) {
      FullJid fullJid = jid.asFullJidIfPossible();
      if (fullJid != null) {
         return this.isParentOf(fullJid);
      } else {
         BareJid bareJid = jid.asBareJidIfPossible();
         if (bareJid != null) {
            return this.isParentOf(bareJid);
         } else {
            DomainFullJid domainFullJid = jid.asDomainFullJidIfPossible();
            return domainFullJid != null ? this.isParentOf(domainFullJid) : this.isParentOf(jid.asDomainBareJid());
         }
      }
   }

   public final String asDomainBareJidString() {
      return this.asDomainBareJid().toString();
   }

   public final int hashCode() {
      return this.toString().hashCode();
   }

   public final boolean equals(Object other) {
      if (other == null) {
         return false;
      } else if (this == other) {
         return true;
      } else {
         return other instanceof CharSequence ? this.equals((CharSequence)other) : false;
      }
   }

   public final boolean equals(CharSequence charSequence) {
      return this.equals(charSequence.toString());
   }

   public final boolean equals(String string) {
      return this.toString().equals(string);
   }

   public final int compareTo(Jid other) {
      String otherString = other.toString();
      String myString = this.toString();
      return myString.compareTo(otherString);
   }
}
