1package eu.siacs.conversations.entities;
  2
  3import org.json.JSONArray;
  4import org.json.JSONException;
  5import org.json.JSONObject;
  6
  7import java.util.Collection;
  8import java.util.Set;
  9import java.util.concurrent.CopyOnWriteArraySet;
 10
 11import eu.siacs.conversations.xmpp.Jid;
 12
 13public class ReadByMarker {
 14
 15	private ReadByMarker() {
 16
 17	}
 18
 19	@Override
 20	public boolean equals(Object o) {
 21		if (this == o) return true;
 22		if (o == null || getClass() != o.getClass()) return false;
 23
 24		ReadByMarker marker = (ReadByMarker) o;
 25
 26		if (fullJid != null ? !fullJid.equals(marker.fullJid) : marker.fullJid != null)
 27			return false;
 28		return realJid != null ? realJid.equals(marker.realJid) : marker.realJid == null;
 29
 30	}
 31
 32	@Override
 33	public int hashCode() {
 34		int result = fullJid != null ? fullJid.hashCode() : 0;
 35		result = 31 * result + (realJid != null ? realJid.hashCode() : 0);
 36		return result;
 37	}
 38
 39	private Jid fullJid;
 40	private Jid realJid;
 41
 42	public Jid getFullJid() {
 43		return fullJid;
 44	}
 45
 46	public Jid getRealJid() {
 47		return realJid;
 48	}
 49
 50	public JSONObject toJson() {
 51		JSONObject jsonObject = new JSONObject();
 52		if (fullJid != null) {
 53			try {
 54				jsonObject.put("fullJid", fullJid.toString());
 55			} catch (JSONException e) {
 56				//ignore
 57			}
 58		}
 59		if (realJid != null) {
 60			try {
 61				jsonObject.put("realJid", realJid.toString());
 62			} catch (JSONException e) {
 63				//ignore
 64			}
 65		}
 66		return jsonObject;
 67	}
 68
 69	public static Set<ReadByMarker> fromJson(final JSONArray jsonArray) {
 70		final Set<ReadByMarker> readByMarkers = new CopyOnWriteArraySet<>();
 71		for(int i = 0; i < jsonArray.length(); ++i) {
 72			try {
 73				readByMarkers.add(fromJson(jsonArray.getJSONObject(i)));
 74			} catch (JSONException e) {
 75				//ignored
 76			}
 77		}
 78		return readByMarkers;
 79	}
 80
 81	public static ReadByMarker from(Jid fullJid, Jid realJid) {
 82		final ReadByMarker marker = new ReadByMarker();
 83		marker.fullJid = fullJid;
 84		marker.realJid = realJid == null ? null : realJid.asBareJid();
 85		return marker;
 86	}
 87
 88	public static ReadByMarker from(Message message) {
 89		final ReadByMarker marker = new ReadByMarker();
 90		marker.fullJid = message.getCounterpart();
 91		marker.realJid = message.getTrueCounterpart();
 92		return marker;
 93	}
 94
 95	public static ReadByMarker from(MucOptions.User user) {
 96		final ReadByMarker marker = new ReadByMarker();
 97		marker.fullJid = user.getFullJid();
 98		marker.realJid = user.getRealJid();
 99		return marker;
100	}
101
102	public static Set<ReadByMarker> from(Collection<MucOptions.User> users) {
103		final Set<ReadByMarker> markers = new CopyOnWriteArraySet<>();
104		for(MucOptions.User user : users) {
105			markers.add(from(user));
106		}
107		return markers;
108	}
109
110	public static ReadByMarker fromJson(JSONObject jsonObject) {
111		ReadByMarker marker = new ReadByMarker();
112		try {
113			marker.fullJid = Jid.of(jsonObject.getString("fullJid"));
114		} catch (JSONException | IllegalArgumentException e) {
115			marker.fullJid = null;
116		}
117		try {
118			marker.realJid = Jid.of(jsonObject.getString("realJid"));
119		} catch (JSONException | IllegalArgumentException e) {
120			marker.realJid = null;
121		}
122		return marker;
123	}
124
125	public static Set<ReadByMarker> fromJsonString(String json) {
126		try {
127			return fromJson(new JSONArray(json));
128		} catch (final JSONException | NullPointerException e) {
129			return new CopyOnWriteArraySet<>();
130		}
131	}
132
133	public static JSONArray toJson(final Set<ReadByMarker> readByMarkers) {
134		final JSONArray jsonArray = new JSONArray();
135		for(final ReadByMarker marker : readByMarkers) {
136			jsonArray.put(marker.toJson());
137		}
138		return jsonArray;
139	}
140
141	public static boolean contains(ReadByMarker needle, final Set<ReadByMarker> readByMarkers) {
142		for(final ReadByMarker marker : readByMarkers) {
143			if (marker.realJid != null && needle.realJid != null) {
144				if (marker.realJid.asBareJid().equals(needle.realJid.asBareJid())) {
145					return true;
146				}
147			} else if (marker.fullJid != null && needle.fullJid != null) {
148				if (marker.fullJid.equals(needle.fullJid)) {
149					return true;
150				}
151			}
152		}
153		return false;
154	}
155
156	public static boolean allUsersRepresented(Collection<MucOptions.User> users, Set<ReadByMarker> markers) {
157		for(MucOptions.User user : users) {
158			if (!contains(from(user),markers)) {
159				return false;
160			}
161		}
162		return true;
163	}
164
165	public static boolean allUsersRepresented(Collection<MucOptions.User> users, Set<ReadByMarker> markers, ReadByMarker marker) {
166		final Set<ReadByMarker> markersCopy = new CopyOnWriteArraySet<>(markers);
167		markersCopy.add(marker);
168		return allUsersRepresented(users, markersCopy);
169	}
170
171}