package com.rapidftr.model;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.rapidftr.RapidFtrApplication;
import com.rapidftr.database.Database;
import com.rapidftr.forms.Form;
import com.rapidftr.repository.ChildRepository;
import com.rapidftr.repository.EnquiryRepository;
import com.rapidftr.repository.PotentialMatchRepository;
import com.rapidftr.utils.RapidFtrDateTime;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;
import static com.rapidftr.database.Database.ChildTableColumn.*;
import static com.rapidftr.utils.JSONArrays.asJSONArray;
import static com.rapidftr.utils.JSONArrays.asList;
public class BaseModel extends JSONObject implements Parcelable {
public static final ObjectMapper JSON_MAPPER = new ObjectMapper();
public static final String FIELD_INTERNAL_ID = "_id";
public static final String FIELD_REVISION_ID = "_rev";
public static final String EMPTY_STRING = "";
public BaseModel(String content) throws JSONException {
super(Strings.nullToEmpty(content).trim().length() == 0 ? "{}" : content);
if (!has(created_at.getColumnName())) {
setCreatedAt(RapidFtrDateTime.now().defaultFormat());
}
if (!has(Database.ChildTableColumn.synced.getColumnName())) {
setSynced(false);
}
if (!has(Database.ChildTableColumn.unique_identifier.getColumnName())) {
setUniqueId(createUniqueId());
}
}
public BaseModel() {
try {
setSynced(false);
setCreatedAt(RapidFtrDateTime.now().defaultFormat());
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
public BaseModel(String id, String owner, String content) throws JSONException {
this(content);
setUniqueId(id);
setCreatedBy(owner);
if (!has(Database.ChildTableColumn.synced.getColumnName())) {
setSynced(false);
}
}
public String getUniqueId() throws JSONException {
return has(unique_identifier.getColumnName()) ? getString(unique_identifier.getColumnName()) : null;
}
public String getInternalId() {
return has(FIELD_INTERNAL_ID) ? getString(FIELD_INTERNAL_ID) : "";
}
public void setUniqueId(String id) throws JSONException {
put(unique_identifier.getColumnName(), id);
}
public String getCreatedAt() throws JSONException {
return getString(created_at.getColumnName());
}
protected void setCreatedAt(String createdAt) throws JSONException {
put(created_at.getColumnName(), createdAt);
}
public String getName() {
return optString(name.getColumnName(), EMPTY_STRING);
}
public void setName(String childName) throws JSONException {
put(name.getColumnName(), childName);
}
public String getLastUpdatedAt() throws JSONException {
return optString(last_updated_at.getColumnName(), null);
}
public Long lastUpdatedAtInMillis(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
try {
return dateFormat.parse(getLastUpdatedAt()).getTime();
} catch (ParseException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
public void setLastUpdatedAt(String lastUpdatedAt) throws JSONException {
put(last_updated_at.getColumnName(), lastUpdatedAt);
}
protected String createUniqueId() throws JSONException {
return UUID.randomUUID().toString();
}
public void generateUniqueId() throws JSONException {
if (has(unique_identifier.getColumnName())) {
/* do nothing */
} else {
setUniqueId(createUniqueId());
}
}
public void setCreatedBy(String owner) throws JSONException {
put(created_by.getColumnName(), owner);
}
public String getJsonString() {
return toString();
}
public boolean isNew() {
return !has(internal_id.getColumnName());
}
@Override
public JSONArray names() {
JSONArray names = super.names();
return names == null ? new JSONArray() : names;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(getJsonString());
}
public void removeFromJSONArray(String key, String value) throws JSONException {
if (!has(key))
return;
JSONArray array = getJSONArray(key);
List<Object> list = asList(array);
list.remove(value);
put(key, asJSONArray(list));
}
public JSONObject values() throws JSONException {
return null;
}
public String getCreatedBy() throws JSONException {
return getString(created_by.getColumnName());
}
@Override
public JSONObject put(String key, Object value) {
if (value != null && value instanceof String) {
value = Strings.emptyToNull(((String) value).trim());
} else if (value != null && value instanceof JSONArray && ((JSONArray) value).length() == 0) {
value = null;
}
try {
return super.put(key, value);
} catch (JSONException e) {
Log.e(RapidFtrApplication.APP_IDENTIFIER, e.getMessage());
}
return null;
}
public void addToJSONArray(String key, Object element) throws JSONException {
JSONArray array = has(key) ? getJSONArray(key) : new JSONArray();
List<Object> list = asList(array);
if (!list.contains(element))
list.add(element);
put(key, asJSONArray(list));
}
public String getString(String key) {
try {
return super.getString(key);
} catch (JSONException e) {
Log.e(RapidFtrApplication.APP_IDENTIFIER, e.getMessage());
}
return null;
}
public String getString(String key, String defaultValue) {
try {
return super.getString(key);
} catch (JSONException ex) {
Log.e(RapidFtrApplication.APP_IDENTIFIER, ex.getMessage());
}
return defaultValue;
}
public void setOrganisation(String userOrg) throws JSONException {
put(created_organisation.getColumnName(), userOrg);
}
public void setSynced(boolean synced) throws JSONException {
put(Database.ChildTableColumn.synced.getColumnName(), synced);
}
public boolean isSynced() {
return optBoolean(Database.ChildTableColumn.synced.getColumnName());
}
public String getShortId() throws JSONException {
if (!has(unique_identifier.getColumnName()))
return null;
int length = getUniqueId().length();
return length > 7 ? getUniqueId().substring(length - 7) : getUniqueId();
}
protected void setHistories() throws JSONException {
String histories = this.optString(History.HISTORIES, null);
if (histories != null)
this.put(History.HISTORIES, new JSONArray(histories));
}
public List<BaseModel> getPotentialMatchingModels(PotentialMatchRepository potentialMatchRepo, ChildRepository childRepo, EnquiryRepository enquiryRepository) throws JSONException {
return new ArrayList<BaseModel>();
}
public String getApiPath() {
return null;
}
public String getApiParameter() {
return null;
}
@Override
public boolean equals(Object other) {
try {
return (other != null && other instanceof JSONObject) && JSON_MAPPER.readTree(toString()).equals(JSON_MAPPER.readTree(other.toString()));
} catch (IOException e) {
return false;
}
}
public List<BaseModel> getConfirmedMatchingModels(PotentialMatchRepository potentialMatchRepository, ChildRepository childRepository, EnquiryRepository enquiryRepository) {
return new ArrayList<BaseModel>();
}
public void addHistory(History history) throws JSONException {
boolean meaningfulHistory = history.has(History.CHANGES) && history.get(History.CHANGES) != null;
if(meaningfulHistory) {
//Android's JSON library does not support 'append', sadly...
if(has(History.HISTORIES)) {
accumulate(History.HISTORIES, history);
} else {
put(History.HISTORIES, new JSONArray(Lists.newArrayList(history)));
}
}
}
public void setLastSyncedAt(String lastSyncedAt) throws JSONException {
put(last_synced_at.getColumnName(), lastSyncedAt);
}
public String getLastSyncedAt() throws JSONException {
return optString(last_synced_at.getColumnName(), null);
}
public String getSyncLog() throws JSONException {
return optString(syncLog.getColumnName(), null);
}
public void setSyncLog(String syncLog1) throws JSONException {
put(syncLog.getColumnName(), syncLog1);
}
public String getRecordedAudio() {
return null;
}
public void putRecordedAudio(String fileName) {
put("recorded_audio", fileName);
}
}