package com.thebluealliance.androidclient.datafeed.deserializers;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.thebluealliance.androidclient.models.ApiStatus;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class APIStatusDeserializer implements JsonDeserializer<ApiStatus> {
private static final int MS_PER_SECOND = 1000;
static final String MAX_SEASON_TAG = "max_season";
static final String CURRENT_SEASON_TAG = "current_season";
static final String FMS_API_DOWN_TAG = "is_datafeed_down";
static final String DOWN_EVENTS_TAG = "down_events";
static final String ANDROID_SETTINGS_TAG = "android";
static final String MIN_APP_VERSION_TAG = "min_app_version";
static final String LATEST_APP_VERSION_TAG = "latest_app_version";
static final String MESSAGE_DICT = "message";
static final String MESSAGE_TEXT = "text";
static final String MESSAGE_EXPIRATION = "expiration";
static final String LAST_OKHTTP_CACHE_CLEAR = "last_cache_clear";
static final String CHAMPS_PIT_LOCATIONS_URL = "cmp_pit_locations_url";
static final String CHAMPS_PIT_LOCATIONS_UPDATE_TIME = "cmp_pit_locations_update_time";
@Override
public ApiStatus deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
if (!json.isJsonObject()) {
throw new JsonParseException("Data is not JsonObject");
}
JsonObject data = json.getAsJsonObject();
ApiStatus status = new ApiStatus();
JsonElement maxSeason = data.get(MAX_SEASON_TAG);
if (maxSeason == null || !maxSeason.isJsonPrimitive()) {
throw new JsonParseException("Max Season is not a primitive");
}
status.setMaxSeason(maxSeason.getAsInt());
JsonElement currentSeason = data.get(CURRENT_SEASON_TAG);
if (currentSeason == null || !currentSeason.isJsonPrimitive()) {
// Default to the current year if not set
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
status.setCurrentSeason(currentYear);
} else {
status.setCurrentSeason(currentSeason.getAsInt());
}
// Ensure that maxSeason always is max(current, given max)
int maxSeasonCheck = Math.max(status.getMaxSeason(), status.getCurrentSeason());
status.setMaxSeason(maxSeasonCheck);
JsonElement fmsApiDown = data.get(FMS_API_DOWN_TAG);
if (fmsApiDown == null || !fmsApiDown.isJsonPrimitive()) {
throw new JsonParseException("Is Datafeed Down is not a primitive");
}
status.setFmsApiDown(fmsApiDown.getAsBoolean());
JsonElement downEvents = data.get(DOWN_EVENTS_TAG);
if (downEvents == null || !downEvents.isJsonArray()) {
throw new JsonParseException("Down Events is not an array");
}
List<String> downKeys = new ArrayList<>();
for (JsonElement eventKey : downEvents.getAsJsonArray()) {
if (!eventKey.isJsonPrimitive()) {
continue;
}
downKeys.add(eventKey.getAsString());
}
status.setDownEvents(downKeys);
JsonElement androidSpecific = data.get(ANDROID_SETTINGS_TAG);
if (androidSpecific == null || !androidSpecific.isJsonObject()) {
throw new JsonParseException("No Android specific settings");
}
JsonObject androidSettings = androidSpecific.getAsJsonObject();
JsonElement minAppVersion = androidSettings.get(MIN_APP_VERSION_TAG);
if (minAppVersion == null || !minAppVersion.isJsonPrimitive()) {
throw new JsonParseException("Min App Version not found");
}
status.setMinAppVersion(minAppVersion.getAsInt());
JsonElement latestAppVersion = androidSettings.get(LATEST_APP_VERSION_TAG);
if (latestAppVersion == null || !latestAppVersion.isJsonPrimitive()) {
throw new JsonParseException("Latest app version not found");
}
status.setLatestAppVersion(latestAppVersion.getAsInt());
JsonElement message = data.get(MESSAGE_DICT);
if (message != null && !message.isJsonNull() && message.isJsonObject()) {
JsonObject adminMessage = data.get(MESSAGE_DICT).getAsJsonObject();
JsonElement messageText = adminMessage.get(MESSAGE_TEXT);
JsonElement messageExpiration = adminMessage.get(MESSAGE_EXPIRATION);
if (messageText == null || messageText.isJsonNull()
|| messageExpiration == null || messageExpiration.isJsonNull()) {
throw new JsonParseException("Message requires text and expiration");
}
status.setHasMessage(true);
status.setMessageText(messageText.getAsString());
status.setMessageExpiration(new Date(messageExpiration.getAsLong() * MS_PER_SECOND)
.getTime());
} else {
status.setHasMessage(false);
}
JsonElement lastCacheClear = data.get(LAST_OKHTTP_CACHE_CLEAR);
if (lastCacheClear != null && !lastCacheClear.isJsonNull() && lastCacheClear.isJsonPrimitive()) {
JsonPrimitive lastCacheTime = lastCacheClear.getAsJsonPrimitive();
long lastTimestamp = lastCacheTime.getAsLong();
status.setLastOkHttpCacheClear(lastTimestamp);
} else {
status.setLastOkHttpCacheClear((long) -1);
}
status.setJsonBlob(json.toString());
return status;
}
}