package jp.sourceforge.nicoro;

import static jp.sourceforge.nicoro.Log.LOG_TAG;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.os.AsyncTask;

import java.io.IOException;
import java.lang.ref.WeakReference;

abstract public class NicoJSONCustomLoader extends AsyncTask<String, Void, ChangeReference<JSONObject>> {
    private volatile HttpUriRequest mHttpRequest;
    private WeakReference<Context> mContext;

    public NicoJSONCustomLoader(Context context) {
        mContext = new WeakReference<Context>(context);
    }

    @Override
    protected ChangeReference<JSONObject> doInBackground(String... params) {
        Context context = mContext.get();
        if (context == null) {
            Log.e(LOG_TAG, "Context is released already");
            return null;
        }

        String hostname = params[0];
        String uri = params[1];

        // TODO ここでCookie取得すべきかどうか
        // 再認証が必要な場合、戻り値のJSONがstatus=fail、errorオブジェクトのcode=NOAUTHになる
        String userSession = NicoroConfig.getCookieUserSession(context);

        HttpUriRequest httpRequest = Util.createRequestGetSingleLineDataFromAPI(
                uri,
                userSession, null);
        mHttpRequest = httpRequest;
        DefaultHttpClient httpClient = Util.createHttpClient();
        JSONObject result = null;
        try {
            httpClient.getCookieStore().clear();
            result = Util.getJSONFromAPI(httpClient,
                    hostname, httpRequest);
        } catch (ClientProtocolException e) {
            Log.e(LOG_TAG, e.toString(), e);
        } catch (IOException e) {
            if (httpRequest.isAborted()) {
                Log.w(LOG_TAG, e.toString(), e);
            } else {
                Log.e(LOG_TAG, e.toString(), e);
            }
        } catch (JSONException e) {
            Log.e(LOG_TAG, e.toString(), e);
        } finally {
            httpClient.getConnectionManager().shutdown();
        }
        mHttpRequest = null;
        if (result == null) {
            return null;
        } else {
            return new ChangeReference<JSONObject>(result);
        }
    }

    @Override
    protected void onCancelled() {
        abortHttpRequest();
        mHttpRequest = null;
    }

    @SuppressWarnings("unchecked")
    public <T extends NicoJSONCustomLoader> T executeWrapper(String hostname, String uri) {
        return (T) execute(hostname, uri);
    }

    private void abortHttpRequest() {
        Util.abortHttpUriRequest(mHttpRequest);
    }
}
