/** filename: com/{{&sdknameLower}}/{{&sdkname}}.java **/
package com.{{&sdknameLower}};

import android.util.Base64;
import android.util.LruCache;
import java.util.HashMap;


/**
 * The {{&sdkname}} SDK
 */
public class {{&sdkname}} {
    private static String domain = "http://localhost";
    private static int port;
    private static int timeout = 30;
    private static CachePolicy cachePolicy = null;
    private static HashMap<String, String> headers = null;
    private static LruCache<String, Result> cache = null;

    /*
     APIs.
     */
    public static API getAPI(String path, String method, CachePolicy cachePolicy) {
        String url = getURL(path);
        if (cachePolicy == null) {
            cachePolicy = {{&sdkname}}.cachePolicy;
        }
        return new API(url, method, cachePolicy);
    }

    /*
    Utility methods.
     */
    private static String getURL(String path) {
        String url = domain;
        if (port > 0) {
            url += ":" + port;
        }
        return url + path;
    }

    /*
     Settings.
     */
    public static String getDomain() {
        return domain;
    }

    public static void setDomain(String domain) {
        {{&sdkname}}.domain = domain;
    }

    public static int getPort() {
        return port;
    }

    public static void setPort(int port) {
        {{&sdkname}}.port = port;
    }

    public static int getTimeout() {
        return timeout;
    }

    public static void setTimeout(int timeout) {
        {{&sdkname}}.timeout = timeout;
    }

    /*
     Headers.
     */
    public static String getApiKey() {
        return getHeader("APIKey");
    }

    public static void setApiKey(String apiKey) {
        setHeader("APIKey", apiKey);
    }

    public static String getAuthorization() {
        return getHeader("Authorization");
    }

    public static void setAuthorization(String authorization) {
        if (authorization.contains("Basic ")) {
            setHeader("Authorization", authorization);
        }
        else if (authorization.endsWith(":")) {
            setHeader("Authorization", "Basic " + Base64.encodeToString(authorization.getBytes(), Base64.NO_WRAP));
        }
        else {
            setHeader("Authorization", "Basic " + Base64.encodeToString((authorization + ":").getBytes(), Base64.NO_WRAP));
        }
    }

    private static String getHeader(String key) {
        if (headers != null) {
            return headers.get(key);
        }
        return null;
    }

    private static void setHeader(String key, String value) {
        if (headers == null) {
            headers = new HashMap<String, String>();
        }
        headers.put(key, value);
    }

    public static HashMap<String, String> getDefaultHeaders() {
        return headers;
    }
    
    /*
     Caching.
     */
    public static CachePolicy getCachePolicy() {
        return cachePolicy;
    }

    public static void setCachePolicy(CachePolicy cachePolicy) {
        {{&sdkname}}.cachePolicy = cachePolicy;
    }
    private static LruCache<String, Result> getCacheDB() {
        if (cache == null) {
            cache = new LruCache<>(500);
        }
        return cache;
    }

    public static Result readCache(String hash) {
        long now = System.currentTimeMillis();
        LruCache<String, Result> cacheDB = getCacheDB();
        Result result = cacheDB.get(hash);
        if (result != null && result.getValidUntil() < now) {
            cacheDB.remove(hash);
            return null;
        }
        return result;
    }

    public static void writeCache(String hash, Result result, long duration) {
        long now = System.currentTimeMillis();
        result.setValidUntil(now + duration);
        getCacheDB().put(hash, result);
    }
}
