package net.outman.hipda.async;

import android.content.Context;
import android.util.Log;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.StringRequest;

import net.outman.hipda.bean.HiSettingsHelper;
import net.outman.hipda.utils.HiUtils;

import org.apache.http.protocol.HTTP;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;

public class HiStringRequest extends StringRequest {

    public HiStringRequest(Context ctx, int method, String url,
                           Listener<String> listener, ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }

    public HiStringRequest(Context ctx, String url, Listener<String> listener,
                           ErrorListener errorListener) {
        super(url, listener, errorListener);
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = super.getHeaders();

        if (headers == null
                || headers.equals(Collections.emptyMap())) {
            headers = new HashMap<String, String>();
        }

        //only send auth cookie to HiPDA
        if (getUrl().startsWith(HiUtils.BaseUrl)) {
            headers.put("Cookie", "cdb_auth=" + HiSettingsHelper.getInstance().getCookieAuth());
        } else {
            headers.remove("Cookie");
        }
        headers.put("User-agent", HiUtils.UserAgent);
        headers.put("Accept-Language", "zh-CN,zh;q=0.8");
        headers.put("Accept-Encoding", "gzip,deflate,sdch");
        headers.put("Accept", "text/html,application/xhtml+xml,application/xml;*/*;q=0.8");
        headers.put("Host", "www.hi-pda.com");

        return headers;
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        String parsed;

        String charset_encode = HttpHeaderParser.parseCharset(response.headers);
        if (charset_encode.equals(HTTP.DEFAULT_CONTENT_CHARSET))
            charset_encode = "GBK";

        boolean detected_charset = false;

        ByteArrayOutputStream decode_content = null;
        String content_encode = response.headers.get("Content-Encoding");
        if (content_encode != null && content_encode.equals("gzip")) {
            try {
                GZIPInputStream inputStream = new GZIPInputStream(new BufferedInputStream
                        (new ByteArrayInputStream(response.data)));

                decode_content = new ByteArrayOutputStream();
                BufferedOutputStream bos = new BufferedOutputStream(decode_content, 4096);

                int bytes;
                byte[] buffer = new byte[4096];
                while ((bytes = inputStream.read(buffer)) > 0) {
                    bos.write(buffer, 0, bytes);

                    if (decode_content.size() > 0 && !detected_charset) {
                        //detect charset
                        String headstr = new String(decode_content.toByteArray(), "UTF-8");

                        int idxmeta = headstr.indexOf("<meta");
                        int idxctx = headstr.indexOf("content=");
                        int idxcharset = headstr.indexOf("charset=");
                        int idxquota = headstr.indexOf("\"", idxcharset);
                        int idxbody = headstr.indexOf("<body");

                        if (idxmeta > 0 && idxcharset > 0 && idxcharset < idxbody && idxctx > idxmeta
                                && idxcharset > idxmeta && idxquota > idxcharset) {
                            charset_encode = headstr.substring(idxcharset + 8, idxquota);
                            detected_charset = true;
                        }

                        if (idxbody > 0)
                            detected_charset = true;
                    }
                }

                inputStream.close();
                bos.close();

            } catch (IOException e) {
                e.printStackTrace();
                decode_content = null;
            }
        }

        try {
            if (decode_content != null)
                parsed = new String(decode_content.toByteArray(), charset_encode);
            else
                parsed = new String(response.data, charset_encode);
        } catch (UnsupportedEncodingException e) {
            Log.e("HiStringRequest", "encoding error", e);
            parsed = "";
        }
        return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
    }

}
