package jp.sourceforge.nicoro;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicLineFormatter;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

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

public class NicoroAPIManager {
	private static final boolean DEBUG_LOGV = Release.IS_DEBUG && true;
	private static final boolean DEBUG_LOGD = Release.IS_DEBUG && true;

	public static final String PATTERN_NICOVIDEO_URL =
		"^https?://.+\\.nicovideo\\.jp/";
    public static final String PATTERN_NICOSEIGA_URL =
        "^https?://.+\\.nicoseiga\\.jp/";

	public static abstract class ParseGetAPIBase {
		protected HashMap<String, String> mData = new HashMap<String, String>();
		private HttpUriRequest mHttpRequest;

		protected abstract String createUri(String videoNumber);

		protected void initialize(DefaultHttpClient httpClient,
				String hostName, String number,
				String cookie, String userAgent) throws ClientProtocolException, IOException {
//			String infoBody = getGetflvResult(httpClient, hostName,
//					createUri(number), cookie, userAgent);
			mHttpRequest = Util.createRequestGetSingleLineDataFromAPI(
					createUri(number), cookie, userAgent);
			String infoBody = Util.getSingleLineDataFromAPI(httpClient,
					hostName, mHttpRequest);
            if (infoBody == null) {
                Log.e(LOG_TAG, Log.buf().append("API failed: hostName=")
                        .append(hostName).append(" number=").append(number)
                        .toString());
            } else {
                initialize(infoBody);
            }
		}

		protected void initialize(String infoBody) {
			String begin = infoBody;
			while (true) {
				int indexKeyEnd = begin.indexOf('=');
				if (indexKeyEnd < 0) {
					break;
				}
				int indexValueBegin = indexKeyEnd + 1;
				int indexValueEnd = begin.indexOf('&', indexValueBegin);

				String key = begin.substring(
						0, indexKeyEnd);
				String value;
				if (indexValueEnd < 0) {
					value = begin.substring(
							indexValueBegin);
				} else {
					value = begin.substring(
							indexValueBegin, indexValueEnd);
				}
				if (DEBUG_LOGV) {
					Log.v(LOG_TAG, Log.buf().append("get: key=").append(key)
							.append(" value=").append(value)
							.toString());
				}
				mData.put(key, value);
				if (indexValueEnd < 0) {
					break;
				}
				begin = begin.substring(indexValueEnd + 1);
			}
		}

//		private static String getGetflvResult(DefaultHttpClient httpClient,
//				String hostName, String uri, String cookie, String userAgent)
//		throws ClientProtocolException, IOException {
//			String result = Util.getSingleLineDataFromAPI(httpClient,
//					hostName, uri, cookie, userAgent);
//			return result;
//		}

		public String get(String key) {
			return mData.get(key);
		}

		public void abort() {
			if (mHttpRequest != null && !mHttpRequest.isAborted()) {
				mHttpRequest.abort();
			}
		}
	}

	public static class ParseGetFLV extends ParseGetAPIBase {
		public static final String HOSTNAME_VIDEO = "www.nicovideo.jp";

		@Override
		protected String createUri(String videoNumber) {
			return "/api/getflv?v=" + videoNumber;
		}

		public void initialize(DefaultHttpClient httpClient,
				String videoNumber,
				String cookie, String userAgent) throws ClientProtocolException, IOException {
			super.initialize(httpClient, HOSTNAME_VIDEO, videoNumber, cookie, userAgent);
		}

		public String getUrl(boolean forceLow) {
			String url = mData.get("url");
			if (url == null) {
				return null;
			}
			if (isGetflvUrlSwf(url)) {
				// swfはURL調整
				url += "as3";
//			} else {
//				if (forceLow && !isGetflvUrlLow(url)) {
//					// 強制的に低画質モード
//					url += "low";
//				}
			}
			if (DEBUG_LOGV) {
				Log.v(LOG_TAG, url);
			}

			return url;
		}
		public String getMs() {
			return mData.get("ms");
		}
		public String getThreadId() {
			return mData.get("thread_id");
		}
	}

	public static class ParseGetFLVLow extends ParseGetFLV {
		@Override
		protected String createUri(String videoNumber) {
//			return super.createUri(videoNumber) + "?eco=1";
			return super.createUri(videoNumber) + "&eco=1";
		}
	}

	public static class ParseGetFLVJikkyo extends ParseGetAPIBase {
		public static final String HOSTNAME_JIKKYO = "jk.nicovideo.jp";

		@Override
		protected String createUri(String videoNumber) {
			return "/api/getflv?v=" + videoNumber;
		}

		public void initialize(DefaultHttpClient httpClient,
				String videoNumber,
				String cookie, String userAgent) throws ClientProtocolException, IOException {
			super.initialize(httpClient, HOSTNAME_JIKKYO, videoNumber, cookie, userAgent);
		}
	}

	public static class ParseGetThreadKey extends ParseGetAPIBase {
		public static final String HOSTNAME = "flapi.nicovideo.jp";

		@Override
		protected String createUri(String threadId) {
			return "/api/getthreadkey?thread=" + threadId;
		}

		public void initialize(DefaultHttpClient httpClient, String threadId,
				String cookie, String userAgent) throws ClientProtocolException, IOException {
			super.initialize(httpClient, HOSTNAME, threadId, cookie, userAgent);
		}

		public String getThreadKey() {
			return mData.get("threadkey");
		}
		public String getForce184() {
			return mData.get("force_184");
		}
	}

	public static String getAuthorizeCookie(DefaultHttpClient httpClient,
			String userAgent) throws ClientProtocolException, IOException {
		HttpPost httpRequest =
			createRequestGetAuthorizeCookie("", "", userAgent);
		return getAuthorizeCookie(httpClient, httpRequest);
	}

	public static String getAuthorizeCookie(DefaultHttpClient httpClient,
			HttpPost httpRequest) throws ClientProtocolException, IOException {
		HttpResponse httpResponse = httpClient.execute(
				new HttpHost("secure.nicovideo.jp", 443, "https"), httpRequest);

		if (DEBUG_LOGD) {
			Log.d(LOG_TAG, "getAuthorizeCookie httpResponse>");
			Util.logHeaders(LOG_TAG, httpResponse.getAllHeaders());
		}
		if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
			return null;
		}

		List<Cookie> cookies = httpClient.getCookieStore().getCookies();
		StringBuilder cookieAuthorize = new StringBuilder(64);
		boolean first = true;
		for (Cookie c : cookies) {
			if (first) {
				first = false;
			} else {
				cookieAuthorize.append("; ");
			}
			if (DEBUG_LOGD) {
				Log.d(LOG_TAG, Log.buf().append(c.getName()).append("=").append(c.getValue()).toString());
			}
			cookieAuthorize.append(c.getName()).append("=").append(c.getValue());
		}
		return cookieAuthorize.toString();
	}

	public static HttpPost createRequestGetAuthorizeCookie(
			String mail, String password, String userAgent
			) throws UnsupportedEncodingException {
		HttpPost httpRequest = new HttpPost("/secure/login?site=niconico");
		List<BasicNameValuePair> postParams = new ArrayList<BasicNameValuePair>();
		postParams.add(new BasicNameValuePair("next_url", ""));
		postParams.add(new BasicNameValuePair("mail", mail));
		postParams.add(new BasicNameValuePair("password", password));
		httpRequest.setEntity(new UrlEncodedFormEntity(postParams, HTTP.UTF_8));
		if (userAgent != null) {
			httpRequest.setHeader("User-Agent", userAgent);
		}
		return httpRequest;
	}

	public String getVideoCookie(DefaultHttpClient httpClient, String uri, String cookie, String userAgent) throws ClientProtocolException, IOException {
		HttpRequest httpRequest = new HttpHead(uri);
		httpRequest.addHeader("Cookie", cookie);
		if (userAgent != null) {
			httpRequest.setHeader("User-Agent", userAgent);
		}
		HttpResponse httpResponse = httpClient.execute(
				new HttpHost("www.nicovideo.jp", 80),
				httpRequest
				);
		if (DEBUG_LOGD) {
			Log.d(LOG_TAG, "getVideoCookie httpResponse>>>");
            Log.d(LOG_TAG, BasicLineFormatter.formatStatusLine(httpResponse.getStatusLine(), null));
			Util.logHeaders(LOG_TAG, httpResponse.getAllHeaders());
			Log.d(LOG_TAG, "<<< httpResponse end");
		}
		StringBuilder cookieVideo = new StringBuilder(64);
		if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
			List<Cookie> cookies = httpClient.getCookieStore().getCookies();
			boolean first = true;
			for (Cookie c : cookies) {
				if (first) {
					first = false;
				} else {
					cookieVideo.append("; ");
				}
				if (DEBUG_LOGD) {
					Log.d(LOG_TAG, Log.buf().append(c.getName())
							.append("=").append(c.getValue()).toString());
				}
				cookieVideo.append(c.getName()).append("=").append(c.getValue());
			}

		}
		if (DEBUG_LOGD) {
			Log.d(LOG_TAG, Log.buf().append("getVideoCookie: ")
					.append(cookieVideo).toString());
		}
		return cookieVideo.toString();
	}

	/**
	 *
	 *
	 * ネットワークからの情報取得が完了するまで処理が返らないので注意
	 *
	 * @param httpRequest
	 * @return
	 */
	public static boolean checkIsCookieUserSessionValid(
			HttpUriRequest httpRequest) {
		DefaultHttpClient httpClient = Util.createHttpClient();
		httpClient.getCookieStore().clear();
		try {
			HttpResponse httpResponse = httpClient.execute(
					httpRequest
					);
			if (DEBUG_LOGD) {
				Log.d(LOG_TAG, BasicLineFormatter.formatStatusLine(httpResponse.getStatusLine(), null));
				Util.logHeaders(LOG_TAG, httpResponse.getAllHeaders());
			}

			int httpStatusCode = httpResponse.getStatusLine().getStatusCode();
			if (httpStatusCode != HttpStatus.SC_OK) {
				return false;
			}

			return checkNiconicoAuthflag(httpResponse);
		} catch (ClientProtocolException e) {
			Log.d(LOG_TAG, e.toString(), e);
			return false;
		} catch (IOException e) {
			Log.d(LOG_TAG, e.toString(), e);
			return false;
		} catch (NumberFormatException e) {
			Log.d(LOG_TAG, e.toString(), e);
			return false;
		}
	}

	/**
	 *
	 * ネットワークからの情報取得が完了するまで処理が返らないので注意
	 *
	 * @param cookieUserSession
	 * @param userAgent
	 * @return
	 */
	public static boolean checkIsCookieUserSessionValid(
			String cookieUserSession, String userAgent) {
		if (cookieUserSession == null || cookieUserSession.length() == 0) {
			return false;
		}

		HttpUriRequest httpRequest = createRequestIsCookieUserSessionValid(
				cookieUserSession, userAgent);
		return checkIsCookieUserSessionValid(httpRequest);
	}

	public static HttpUriRequest createRequestIsCookieUserSessionValid(
			String cookieUserSession, String userAgent) {
		HttpUriRequest httpRequest = new HttpHead("http://www.nicovideo.jp/");
		httpRequest.addHeader("Cookie", cookieUserSession);
		if (userAgent != null) {
			httpRequest.setHeader("User-Agent", userAgent);
		}
		if (DEBUG_LOGD) {
			Util.logHeaders(LOG_TAG, httpRequest.getAllHeaders());
		}
		return httpRequest;
	}

	public static boolean checkNiconicoAuthflag(HttpResponse httpResponse) {
		Header authflag = httpResponse.getFirstHeader("x-niconico-authflag");
		if (authflag == null) {
			return false;
		}
		try {
			return Integer.parseInt(authflag.getValue()) != 0;
		} catch (NumberFormatException e) {
			return false;
		}
	}

	public static class VideoPlayerIntentCreator {
		private ParseGetFLV mParseGetFLV;
		private ParseGetThreadKey mParseGetThreadKey;

		public Intent create(Context context,
				String videoNumber, String cookieUserSession,
				String cookieNicoHistory, String userId,
				String userAgent, boolean forceLow
				) throws FailPreparePlayVideoException,
				ClientProtocolException, IOException {
			DefaultHttpClient httpClient = Util.createHttpClient();
			httpClient.getCookieStore().clear();
			assert mParseGetFLV == null;
			if (forceLow) {
				mParseGetFLV = new ParseGetFLVLow();
			} else {
				mParseGetFLV = new ParseGetFLV();
			}
			mParseGetFLV.initialize(httpClient,
					videoNumber,
					cookieUserSession, userAgent);
			assert mParseGetThreadKey == null;
			mParseGetThreadKey = new ParseGetThreadKey();
			final String getflvUrl = mParseGetFLV.getUrl(forceLow);
			final String getflvMs = mParseGetFLV.getMs();
			final String getflvThreadId = mParseGetFLV.getThreadId();
			mParseGetThreadKey.initialize(httpClient,
					getflvThreadId, cookieUserSession, userAgent);

			if (getflvUrl == null
					|| getflvMs == null
					|| getflvThreadId == null) {
				throw new FailPreparePlayVideoException(
						context.getString(R.string.errormessage_getflv_fail));
			}

			Class<?> activityClass;
			// 動画タイプチェック＆Activity選択
			if (isGetflvUrlFlv(getflvUrl)) {
				// flv
				activityClass = NicoroFFmpegPlayer.class;
			} else if (isGetflvUrlMp4(getflvUrl)) {
				// mp4
				SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
				if (sharedPreferences.getBoolean(
						context.getString(R.string.pref_key_mp4_mediaplayer), true)) {
					activityClass = NicoroMediaPlayer.class;
				} else {
					activityClass = NicoroFFmpegPlayer.class;
				}
			} else if (isGetflvUrlSwf(getflvUrl)) {
				// swf
//				// 未対応
//				Log.w(LOG_TAG, "SWF is unsupported");
//				FailPreparePlayVideoException e = new FailPreparePlayVideoException();
//				e.setExtraMessage("swf形式は未対応です");
//				throw e;
				activityClass = NicoroSwfPlayer.class;
			} else {
				// 想定外
				Log.w(LOG_TAG, Log.buf().append("Unrecognized video URL:")
						.append(getflvUrl).toString());
				// とりあえずデフォルトで起動を試みる
				activityClass = NicoroFFmpegPlayer.class;
			}

			return new Intent(context, activityClass)
				.putExtra(
						AbstractNicoroPlayer.INTENT_NAME_VIDEO_URL,
						getflvUrl)
				.putExtra(
						AbstractNicoroPlayer.INTENT_NAME_COOKIE,
						cookieNicoHistory)
				.putExtra(
						AbstractNicoroPlayer.INTENT_NAME_VIDEO_NUMBER,
						videoNumber)
				.putExtra(
						AbstractNicoroPlayer.INTENT_NAME_MESSAGE_URL,
						getflvMs)
				.putExtra(
						AbstractNicoroPlayer.INTENT_NAME_THREAD_ID,
						getflvThreadId)
				.putExtra(
						AbstractNicoroPlayer.INTENT_NAME_USER_ID,
						userId)
				.putExtra(
						AbstractNicoroPlayer.INTENT_NAME_THREAD_KEY,
						mParseGetThreadKey.getThreadKey())
				.putExtra(
						AbstractNicoroPlayer.INTENT_NAME_FORCE_184,
						mParseGetThreadKey.getForce184())
				.putExtra(
						AbstractNicoroPlayer.INTENT_NAME_COOKIE_USER_SESSION,
						cookieUserSession);
		}

		public void abort() {
			if (mParseGetFLV != null) {
				mParseGetFLV.abort();
			}
			if (mParseGetThreadKey != null) {
				mParseGetThreadKey.abort();
			}
		}
	}

//	public static Intent createVideoPlayerIntent(Context context,
//			String videoNumber, String cookieUserSession,
//			String cookieNicoHistory, String userId,
//			String userAgent, boolean forceLow)
//	throws FailPreparePlayVideoException {
//		try {
//			DefaultHttpClient httpClient = Util.createHttpClient();
//			httpClient.getCookieStore().clear();
//			ParseGetFLV parseGetFLV;
//			if (forceLow) {
//				parseGetFLV = new ParseGetFLVLow();
//			} else {
//				parseGetFLV = new ParseGetFLV();
//			}
//			parseGetFLV.initialize(httpClient,
//					videoNumber,
//					cookieUserSession, userAgent);
//			ParseGetThreadKey parseGetThreadKey = new ParseGetThreadKey();
//			final String getflvUrl = parseGetFLV.getUrl(forceLow);
//			final String getflvMs = parseGetFLV.getMs();
//			final String getflvThreadId = parseGetFLV.getThreadId();
//			parseGetThreadKey.initialize(httpClient,
//					getflvThreadId, cookieUserSession, userAgent);
//
//			if (getflvUrl == null
//					|| getflvMs == null
//					|| getflvThreadId == null) {
//				throw new FailPreparePlayVideoException();
//			}
//
//			Class<?> activityClass = null;
//			// 動画タイプチェック＆Activity選択
//			if (isGetflvUrlFlv(getflvUrl)) {
//				// flv
//				activityClass = NicoroFFmpegPlayer.class;
//			} else if (isGetflvUrlMp4(getflvUrl)) {
//				// mp4
//				SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
//				if (sharedPreferences.getBoolean(
//						context.getString(R.string.pref_key_mp4_mediaplayer), true)) {
//					activityClass = NicoroMediaPlayer.class;
//				} else {
//					activityClass = NicoroFFmpegPlayer.class;
//				}
//			} else if (isGetflvUrlSwf(getflvUrl)) {
//				// swf
////				// 未対応
////				Log.w(LOG_TAG, "SWF is unsupported");
////				FailPreparePlayVideoException e = new FailPreparePlayVideoException();
////				e.setExtraMessage("swf形式は未対応です");
////				throw e;
//				activityClass = NicoroSwfPlayer.class;
//			} else {
//				// 想定外
//				Log.w(LOG_TAG, Log.buf().append("Unrecognized video URL:")
//						.append(getflvUrl).toString());
//				// とりあえずデフォルトで起動を試みる
//				activityClass = NicoroFFmpegPlayer.class;
//			}
//
//			if (activityClass != null) {
//				return new Intent(context, activityClass)
//					.putExtra(
//							AbstractNicoroPlayer.INTENT_NAME_VIDEO_URL,
//							getflvUrl)
//					.putExtra(
//							AbstractNicoroPlayer.INTENT_NAME_COOKIE,
//							cookieNicoHistory)
//					.putExtra(
//							AbstractNicoroPlayer.INTENT_NAME_VIDEO_NUMBER,
//							videoNumber)
//					.putExtra(
//							AbstractNicoroPlayer.INTENT_NAME_MESSAGE_URL,
//							getflvMs)
//					.putExtra(
//							AbstractNicoroPlayer.INTENT_NAME_THREAD_ID,
//							getflvThreadId)
//					.putExtra(
//							AbstractNicoroPlayer.INTENT_NAME_USER_ID,
//							userId)
//					.putExtra(
//							AbstractNicoroPlayer.INTENT_NAME_THREAD_KEY,
//							parseGetThreadKey.getThreadKey())
//					.putExtra(
//							AbstractNicoroPlayer.INTENT_NAME_FORCE_184,
//							parseGetThreadKey.getForce184())
//					.putExtra(
//							AbstractNicoroPlayer.INTENT_NAME_COOKIE_USER_SESSION,
//							cookieUserSession);
//			}
//		} catch (ClientProtocolException e) {
//			Log.d(LOG_TAG, e.getMessage(), e);
//		} catch (IOException e) {
//			Log.d(LOG_TAG, e.getMessage(), e);
//		}
//		return null;
//	}

	public static Intent createJikkyoPlayerIntent(Context context,
			String jikkyoNumber, String cookieUserSession,
			String cookieNicoHistory, String userId,
			String userAgent)
	throws FailPreparePlayVideoException {
//		try {
//			DefaultHttpClient httpClient = Util.createHttpClient();
//			httpClient.getCookieStore().clear();
//			ParseGetFLVJikkyo parseGetFLVJikkyo = new ParseGetFLVJikkyo();
//			parseGetFLVJikkyo.initialize(httpClient,
//					jikkyoNumber,
//					cookieUserSession, userAgent);

			Intent intent = new Intent(context, NicoroJikkyoPlayer.class);
//			intent.putExtra(
//					NicoroJikkyoPlayer.INTENT_NAME_COOKIE,
//					cookieNicoHistory);
			intent.putExtra(
					NicoroJikkyoPlayer.INTENT_NAME_JIKKYO_NUMBER,
					jikkyoNumber);
//			intent.putExtra(
//					NicoroJikkyoPlayer.INTENT_NAME_MESSAGE_URL,
//					parseGetFLVJikkyo.get("ms"));
//			intent.putExtra(
//					NicoroJikkyoPlayer.INTENT_NAME_MESSAGE_PORT,
//					parseGetFLVJikkyo.get("ms_port"));
//			intent.putExtra(
//					NicoroJikkyoPlayer.INTENT_NAME_THREAD_ID,
//					parseGetFLVJikkyo.get("thread_id"));
//			intent.putExtra(
//					NicoroJikkyoPlayer.INTENT_NAME_USER_ID,
//					parseGetFLVJikkyo.get("user_id"));
//			intent.putExtra(
//					NicoroJikkyoPlayer.INTENT_NAME_HTTP_PORT,
//					parseGetFLVJikkyo.get("http_port"));
			return intent;
//		} catch (ClientProtocolException e) {
//			Log.d(LOG_TAG, e.getMessage(), e);
//		} catch (IOException e) {
//			Log.d(LOG_TAG, e.getMessage(), e);
//		}
//
//		return null;
	}

    public static Intent createLivePlayerIntent(Context context,
            String liveNumber, String cookieUserSession,
            String title, String description,
            String cookieNicoHistory, String userId,
            String userAgent)
    throws FailPreparePlayVideoException {
        // descriptionの改行除去
        if (description != null) {
            description = description.replaceAll("[\\r\\n]+", " ");
        }

        Intent intent = new Intent(context, NicoroLivePlayer.class)
            .putExtra(
                    NicoroLivePlayer.INTENT_NAME_LIVE_NUMBER,
                    liveNumber)
            .putExtra(
                    AbstractNicoroPlayer.INTENT_NAME_COOKIE_USER_SESSION,
                    cookieUserSession)
            .putExtra(
                    NicoroLivePlayer.INTENT_NAME_TITLE,
                    title)
            .putExtra(
                    NicoroLivePlayer.INTENT_NAME_DESCRIPTION,
                    description)
                    ;
        return intent;
    }

	/**
	 *
	 * ネットワークからの情報取得が完了するまで処理が返らないので注意
	 *
	 * @param httpClient
	 * @param videoNumber
	 * @param cookieUserSession
	 * @param forceLow
	 * @param userAgent
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String getCookieNicoHistory(DefaultHttpClient httpClient,
			String videoNumber, String cookieUserSession,
			boolean forceLow, String userAgent)
	throws ClientProtocolException, IOException {
		HttpUriRequest httpRequest = createGetCookieNicoHistory(
				videoNumber, cookieUserSession, forceLow, userAgent);
		return getCookieNicoHistory(httpClient, httpRequest);
	}

	/**
	 *
	 * ネットワークからの情報取得が完了するまで処理が返らないので注意
	 *
	 * @param httpClient
	 * @param httpRequest
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String getCookieNicoHistory(DefaultHttpClient httpClient,
			HttpUriRequest httpRequest)
	throws ClientProtocolException, IOException {
		HttpResponse httpResponse = httpClient.execute(
				new HttpHost("www.nicovideo.jp", 80),
				httpRequest
				);
		if (DEBUG_LOGD) {
			Log.d(LOG_TAG, "==========getCookieNicoHistory httpResponse==========");
            Log.d(LOG_TAG, BasicLineFormatter.formatStatusLine(httpResponse.getStatusLine(), null));
			Util.logHeaders(LOG_TAG, httpResponse.getAllHeaders());
			Log.d(LOG_TAG, "==========httpResponse end==========");
		}
		String cookieVideo = null;
		if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
			List<Cookie> cookies = httpClient.getCookieStore().getCookies();
			for (Cookie c : cookies) {
				if ("nicohistory".equals(c.getName())) {
					cookieVideo = c.getName() + "=" + c.getValue();
					break;
				}
			}
		}
		if (DEBUG_LOGD) {
			Log.d(LOG_TAG, Log.buf().append("getCookieNicoHistory: ")
					.append(cookieVideo).toString());
		}
		return cookieVideo;
	}

	public static HttpUriRequest createGetCookieNicoHistory(
			String videoNumber, String cookieUserSession,
			boolean forceLow, String userAgent) {
		String uri = "/watch/" + videoNumber;
		if (forceLow) {
			uri += "?eco=1";
		}
		HttpUriRequest httpRequest = new HttpHead(uri);
//		HttpRequest httpRequest = new HttpGet(uri);
		httpRequest.addHeader("Cookie", cookieUserSession);
		if (userAgent != null) {
			httpRequest.setHeader("User-Agent", userAgent);
		}
		return httpRequest;
	}

	public static boolean isGetflvUrlFlv(String url) {
		return url.indexOf("?v=") >= 0;
	}
	public static boolean isGetflvUrlMp4(String url) {
		return url.indexOf("?m=") >= 0;
	}
	public static boolean isGetflvUrlSwf(String url) {
		return url.indexOf("?s=") >= 0;
	}
	public static boolean isGetflvUrlLow(String url) {
		return url.endsWith("low");
	}

	public static boolean isVideoNumberSwf(String videoNumber) {
		return videoNumber.startsWith("nm");
	}
}
