/* == This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2016, Enno Gottschalk <mrmaffen@googlemail.com>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
package org.tomahawk.libtomahawk.infosystem.charts;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.jdeferred.Deferred;
import org.jdeferred.Promise;
import org.tomahawk.libtomahawk.resolver.ScriptAccount;
import org.tomahawk.libtomahawk.resolver.ScriptJob;
import org.tomahawk.libtomahawk.resolver.ScriptObject;
import org.tomahawk.libtomahawk.resolver.ScriptPlugin;
import org.tomahawk.libtomahawk.utils.ADeferredObject;
import org.tomahawk.libtomahawk.utils.GsonHelper;
import android.support.v4.util.Pair;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ScriptChartsProvider implements ScriptPlugin {
public static final String TAG = ScriptChartsProvider.class.getSimpleName();
// cache the result for a maximum of 12 hours
private static final long CACHE_TIME = 43200000L;
private ScriptAccount mScriptAccount;
private ScriptObject mScriptObject;
private Map<String, Pair<Long, ScriptChartsResult>> mCachedResults = new ConcurrentHashMap<>();
public ScriptChartsProvider(ScriptObject scriptObject, ScriptAccount account) {
mScriptObject = scriptObject;
mScriptAccount = account;
}
public Promise<ScriptChartsCountryCodes, Throwable, Void> getCountryCodes() {
final Deferred<ScriptChartsCountryCodes, Throwable, Void> deferred =
new ADeferredObject<>();
ScriptJob.start(mScriptObject, "countryCodes", new ScriptJob.ResultsObjectCallback() {
@Override
public void onReportResults(JsonObject results) {
ScriptChartsCountryCodes chartsCountryCodes = new ScriptChartsCountryCodes();
chartsCountryCodes.defaultCode = results.get("defaultCode").getAsString();
List<Pair<String, String>> codes = new ArrayList<>();
JsonArray rawCodes = results.getAsJsonArray("codes");
for (JsonElement result : rawCodes) {
JsonObject code = (JsonObject) result;
for (Map.Entry<String, JsonElement> member : code.entrySet()) {
Pair<String, String> pair =
new Pair<>(member.getKey(), member.getValue().getAsString());
codes.add(pair);
}
}
chartsCountryCodes.codes = codes;
deferred.resolve(chartsCountryCodes);
}
});
return deferred;
}
public Promise<List<Pair<String, String>>, Throwable, Void> getTypes() {
final Deferred<List<Pair<String, String>>, Throwable, Void> deferred
= new ADeferredObject<>();
ScriptJob.start(mScriptObject, "types", new ScriptJob.ResultsArrayCallback() {
@Override
public void onReportResults(JsonArray results) {
List<Pair<String, String>> types = new ArrayList<>();
for (JsonElement result : results) {
JsonObject type = (JsonObject) result;
for (Map.Entry<String, JsonElement> member : type.entrySet()) {
Pair<String, String> pair =
new Pair<>(member.getKey(), member.getValue().getAsString());
types.add(pair);
}
}
deferred.resolve(types);
}
});
return deferred;
}
public Promise<ScriptChartsResult, Throwable, Void> getCharts(final String countryCode,
final String type) {
final Deferred<ScriptChartsResult, Throwable, Void> deferred = new ADeferredObject<>();
final String cacheKey = getCacheKey(countryCode, type);
final Pair<Long, ScriptChartsResult> pair = mCachedResults.get(cacheKey);
if (pair != null && pair.first > System.currentTimeMillis() - CACHE_TIME) {
Log.d(TAG, "Using cached charts for " + mScriptAccount.getName()
+ ": countryCode=" + countryCode + ", type=" + type
+ " - containing " + pair.second.results.size() + " results");
deferred.resolve(pair.second);
} else {
Log.d(TAG, "Getting fresh charts for " + mScriptAccount.getName() + ": countryCode="
+ countryCode + ", type=" + type);
Map<String, Object> args = new HashMap<>();
args.put("countryCode", countryCode);
args.put("type", type);
ScriptJob.start(mScriptObject, "charts", args, new ScriptJob.ResultsObjectCallback() {
@Override
public void onReportResults(JsonObject results) {
ScriptChartsResult result =
GsonHelper.get().fromJson(results, ScriptChartsResult.class);
Pair<Long, ScriptChartsResult> pair =
new Pair<>(System.currentTimeMillis(), result);
mCachedResults.put(cacheKey, pair);
Log.d(TAG, "Received fresh charts for " + mScriptAccount.getName()
+ ": countryCode=" + countryCode + ", type=" + type
+ " - containing " + result.results.size() + " results");
deferred.resolve(result);
}
});
}
return deferred;
}
private String getCacheKey(String countryCode, String type) {
return countryCode + "\t\t" + type;
}
@Override
public ScriptAccount getScriptAccount() {
return mScriptAccount;
}
@Override
public ScriptObject getScriptObject() {
return mScriptObject;
}
}