package com.example.wordbook.task;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
import android.util.TimingLogger;

import com.example.wordbook.common.Common;
import com.example.wordbook.common.Message;
import com.example.wordbook.provider.WBData;
import com.example.wordbook.provider.WBHelper;
import com.example.wordbook.provider.WBProvider;

/**
 * 単語帳DB問題集入力タスク
 */
public class AsyncTaskImport extends AsyncTaskBase {

	/** TAG */
	private static final String TAG = AsyncTaskImport.class.getSimpleName();

	/**
	 * コンストラクタ
	 * 
	 * @param activity
	 *            アクティビティ
	 * @param horizontal
	 *            水平進捗バー表示設定
	 */
	public AsyncTaskImport(Activity activity, boolean horizontal) {
		super(activity, horizontal);
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.os.AsyncTask#onPreExecute()
	 */
	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		Log.d(TAG, "onPreExecute()");
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
	 */
	@Override
	protected void onPostExecute(Integer result) {

		// 処理成功
		if (result > 0) {
			// 表示更新
			if (mActivity instanceof OnAsyncTaskFinished) {
				((OnAsyncTaskFinished) mActivity).onAsyncTaskFinished();
			}
			// 成功通知
			Message.show(mActivity, Message.ID.IMPORT_COMPLETE);
		} else {
			// 失敗通知
			Message.show(mActivity, Message.ID.IMPORT_FAILED);
		}

		Log.d(TAG, "onPostExecute()=" + result);
		super.onPostExecute(result);
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.os.AsyncTask#doInBackground(Params[])
	 */
	@Override
	protected Integer doInBackground(String... params) {
		Log.d(TAG, "doInBackground()");
		int result = 0;

		// パラメータ取得
		String file = "";
		if (params == null || params.length == 0) {
			return result;
		}
		file = params[0];

		// インデックス取得
		int index = Common.getWordbookPrefIndex(mActivity
				.getApplicationContext());
		if (index == 0) {
			return result;
		}

		// Indexの問題集入力
		final int DB_MODE = 1;
		TimingLogger logger = new TimingLogger("dbg", "Import()");

		// 入力ファイルパス
		final String path = Common.WORDBOOK_DIRECTORY + file;
		// 対象設定
		String line;
		ContentValues cv;

		FileInputStream fis = null;
		InputStreamReader isr = null;
		LineNumberReader lnr = null;
		try {
			fis = new FileInputStream(path);
			isr = new InputStreamReader(fis, "UTF-8");
			lnr = new LineNumberReader(isr);

			// ライン数取得
			lnr.mark(fis.available());
			while (lnr.readLine() != null) {
			}
			int line_max = lnr.getLineNumber();
			lnr.reset();

			// プログレスバー設定
			final int STEP = 20;
			int line_step = line_max / STEP;
			publishProgress(0, line_max);

			switch (DB_MODE) {
			case 0:
				// by ContentProvider
				ContentResolver cr = mActivity.getContentResolver();
				Uri uri = WBProvider.INFO_CONTENT_URI;
				// 一行一件
				while ((line = lnr.readLine()) != null) {
					cv = getImportContent(line, index, result + 1);
					if (cv == null) {
						continue;
					}
					cr.insert(uri, cv);
					// プログレスバー更新
					if (++result >= line_step) {
						publishProgress(result);
						line_step += line_max / STEP;
					}
				}
				logger.addSplit("ContentProvider");
				break;
			default:
				// by SQLiteOpenHelper
				WBHelper helper = WBHelper.getInstance(mActivity);
				SQLiteDatabase db = helper.getWritableDatabase();
				// トランザクション
				try {
					// トランザクション開始
					db.beginTransaction();
					// 一行一件
					while ((line = lnr.readLine()) != null) {
						cv = getImportContent(line, index, result + 1);
						if (cv == null) {
							continue;
						}
						db.insert(WBData.TABLE_NAME_INFO, null, cv);
						// プログレスバー更新
						if (++result >= line_step) {
							publishProgress(result);
							line_step += line_max / STEP;
						}
					}
					// トランザクション成功
					db.setTransactionSuccessful();
				} finally {
					// トランザクション終了
					db.endTransaction();
				}
				db.close();
				helper.close();
				logger.addSplit("SQLiteOpenHelper");
				break;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (lnr != null) {
					lnr.close();
				}
				if (isr != null) {
					isr.close();
				}
				if (fis != null) {
					fis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		if (result > 0) {
			// 設定ファイル更新
			List<Map<String, Object>> list = Common
					.getWordbookPrefList(mActivity.getApplicationContext());
			String title = Common.normWordbookPrefTitle(list,
					file.replace(Common.WORDBOOK_EXT, ""));
			Common.modWordbookPref(mActivity.getApplicationContext(), index,
					title, new int[] { result, result, 0, 0 }, -1);
		}

		// 処理時間計測
		logger.dumpToLog();

		return result;
	}

	/**
	 * 入力用コンテント生成
	 * 
	 * @param line
	 *            解析対象文字列
	 * @param index
	 *            INFO_FILE:ファイル番号用
	 * @param result
	 *            INFO_NUM:データ番号用
	 * @return 入力用コンテント
	 */
	private ContentValues getImportContent(String line, int index, int result) {
		final int ELEMENT_LENGTH = 6;
		final int LEVEL_MAX = 7;
		final int FLAG_MAX = 7;
		final String[] elements = line.split(",");
		int level, flag, ok, ng;
		String q, a, d1, d2;

		if (elements.length < ELEMENT_LENGTH) {
			return null;
		}

		try {
			level = Integer.parseInt(elements[0]);
			if (level < 0 || level > LEVEL_MAX) {
				level = 0;
			}
		} catch (NumberFormatException e) {
			level = 0;
		}
		try {
			flag = Integer.parseInt(elements[1]);
			if (flag < 0 || flag > FLAG_MAX) {
				flag = 0;
			}
		} catch (NumberFormatException e) {
			flag = 0;
		}
		try {
			ok = Integer.parseInt(elements[2]);
			if (ok < 0) {
				ok = 0;
			}
		} catch (NumberFormatException e) {
			ok = 0;
		}
		try {
			ng = Integer.parseInt(elements[3]);
			if (ng < 0) {
				ng = 0;
			}
		} catch (NumberFormatException e) {
			ng = 0;
		}
		q = elements[4];
		if (q.length() == 0) {
			return null;
		}
		a = elements[5];
		if (a.length() == 0) {
			return null;
		}
		d1 = "";
		if (elements.length > 6) {
			d1 = elements[6];
		}
		d2 = "";
		if (elements.length > 7) {
			d2 = elements[7];
		}

		// WBData形式
		ContentValues cv = new ContentValues();
		cv.clear();
		cv.put(WBData.InfoColumns.INFO_FILE, index);
		cv.put(WBData.InfoColumns.INFO_NUM, result);
		cv.put(WBData.InfoColumns.INFO_STAT, 0);
		cv.put(WBData.InfoColumns.INFO_LEVEL, level);
		cv.put(WBData.InfoColumns.INFO_FLAG, flag);
		cv.put(WBData.InfoColumns.INFO_OK, ok);
		cv.put(WBData.InfoColumns.INFO_NG, ng);
		cv.put(WBData.InfoColumns.INFO_QUESTION, q);
		cv.put(WBData.InfoColumns.INFO_ANSWER, a);
		cv.put(WBData.InfoColumns.INFO_DATA1, d1);
		cv.put(WBData.InfoColumns.INFO_DATA2, d2);

		return cv;
	}

}
