package jp.agentec.abook.abv.bl.data;

import java.util.ArrayList;
import java.util.List;

import jp.agentec.abook.abv.bl.common.db.SQLiteDatabase;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.tables.LContentObjectLog;
import jp.agentec.abook.abv.bl.data.tables.LContentPageReadingLog;
import jp.agentec.abook.abv.bl.data.tables.LContentReadingLog;
import jp.agentec.abook.abv.bl.data.tables.MAcms;
import jp.agentec.abook.abv.bl.data.tables.MAppConfig;
import jp.agentec.abook.abv.bl.data.tables.MCategory;
import jp.agentec.abook.abv.bl.data.tables.MGroup;
import jp.agentec.abook.abv.bl.data.tables.MMemberInfo;
import jp.agentec.abook.abv.bl.data.tables.MOperationGroupMaster;
import jp.agentec.abook.abv.bl.data.tables.MPasswordLockInfo;
import jp.agentec.abook.abv.bl.data.tables.MServiceOption;
import jp.agentec.abook.abv.bl.data.tables.MWorkerGroup;
import jp.agentec.abook.abv.bl.data.tables.ROperationContent;
import jp.agentec.abook.abv.bl.data.tables.RContentCategory;
import jp.agentec.abook.abv.bl.data.tables.RContentGroup;
import jp.agentec.abook.abv.bl.data.tables.ROperationGroupMasterOperation;
import jp.agentec.abook.abv.bl.data.tables.RTaskWorkerGroup;
import jp.agentec.abook.abv.bl.data.tables.SQLiteTableScript;
import jp.agentec.abook.abv.bl.data.tables.TContent;
import jp.agentec.abook.abv.bl.data.tables.TContentBookmark;
import jp.agentec.abook.abv.bl.data.tables.TContentDownloadQueue;
import jp.agentec.abook.abv.bl.data.tables.TContentMarking;
import jp.agentec.abook.abv.bl.data.tables.TContentMemo;
import jp.agentec.abook.abv.bl.data.tables.TContentOldPdf;
import jp.agentec.abook.abv.bl.data.tables.TContentPage;
import jp.agentec.abook.abv.bl.data.tables.TContentResource;
import jp.agentec.abook.abv.bl.data.tables.TContentServerSearched;
import jp.agentec.abook.abv.bl.data.tables.TContentTag;
import jp.agentec.abook.abv.bl.data.tables.TEnquete;
import jp.agentec.abook.abv.bl.data.tables.TMarkingSetting;
import jp.agentec.abook.abv.bl.data.tables.TOperation;
import jp.agentec.abook.abv.bl.data.tables.TPushMessage;
import jp.agentec.abook.abv.bl.data.tables.TTaskReportStatus;
import jp.agentec.abook.abv.bl.data.tables.TSppDevice;
import jp.agentec.abook.abv.bl.data.tables.TTask;
import jp.agentec.abook.abv.bl.data.tables.TTaskReport;
import jp.agentec.abook.abv.bl.data.tables.TTaskReportItems;
import jp.agentec.abook.abv.bl.data.tables.TTaskReportSend;
import jp.agentec.adf.util.StringUtil;

public class ABVDataOpenHelper {
	private Throwable lastError = null;
	private boolean createFailed = false;
	private static final String TAG = "DATA";
	
	public Throwable getLastError() {
		return lastError;
	}
	
	public boolean isCreated() {
		return !createFailed;
	}

	private List<SQLiteTableScript> getTableScripts() {
		List<SQLiteTableScript> iTableScripts = new ArrayList<SQLiteTableScript>();

		//	DDLの実行順に追加すること
		iTableScripts.add(new TContent());

		iTableScripts.add(new MMemberInfo());
		iTableScripts.add(new MGroup());
		iTableScripts.add(new MCategory());
		iTableScripts.add(new RContentCategory());
		iTableScripts.add(new RContentGroup());
		iTableScripts.add(new TContentDownloadQueue());
		iTableScripts.add(new TContentTag());
		iTableScripts.add(new LContentReadingLog());
		iTableScripts.add(new LContentPageReadingLog());
		iTableScripts.add(new LContentObjectLog());
		iTableScripts.add(new MPasswordLockInfo());
		iTableScripts.add(new TContentOldPdf());
		iTableScripts.add(new TContentServerSearched());

		iTableScripts.add(new MAcms());
		iTableScripts.add(new MAppConfig());
		iTableScripts.add(new TContentResource());
		iTableScripts.add(new TContentBookmark());
		iTableScripts.add(new TContentPage());
		iTableScripts.add(new TContentMemo());
		iTableScripts.add(new TContentMarking());
		iTableScripts.add(new MServiceOption());
		iTableScripts.add(new TMarkingSetting());
		iTableScripts.add(new TEnquete());

		iTableScripts.add(new MWorkerGroup());
		iTableScripts.add(new TOperation());
		iTableScripts.add(new RTaskWorkerGroup());
		iTableScripts.add(new ROperationContent());
		iTableScripts.add(new TTask());
		iTableScripts.add(new TTaskReport());
		iTableScripts.add(new TTaskReportSend());
		iTableScripts.add(new TTaskReportItems());
		iTableScripts.add(new TPushMessage());
		iTableScripts.add(new TTaskReportStatus());

		// SPP通信端末管理テーブルをスクリプトに追加
		iTableScripts.add(new TSppDevice());

		// カテゴリ選択機能テーブルをスクリプトに追加
		iTableScripts.add(new MOperationGroupMaster());
		iTableScripts.add(new ROperationGroupMasterOperation());

		return iTableScripts; 
	}


	public void onCreate(SQLiteDatabase db) {
		Logger.i(TAG, "create database version " + db.getVersion());
		List<SQLiteTableScript> iTableScripts = getTableScripts();
		
		try {
			List<String> ddl;
			
			db.beginTransaction();
			
			for (SQLiteTableScript iTableScript : iTableScripts) {
				ddl = iTableScript.getCreateScript(db.getVersion());
				for (String sql : ddl) {
					if (!StringUtil.isNullOrWhiteSpace(sql)) {
						Logger.d(TAG, sql);
						db.execSQL(sql);
					}
				}
			}
			
			db.setTransactionSuccessful();	//	commit
			createFailed = false;
		} catch (Exception e) {
			lastError = e;
			createFailed = true;
		} finally {
			db.endTransaction();
		}
	}

	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		Logger.i(TAG, String.format("upgrade database to version %d from version : %d", newVersion, oldVersion));
		List<SQLiteTableScript> iTableScripts = getTableScripts();
		
		try {
			List<String> ddl;
			List<String> dml;
			
			db.beginTransaction();
			
			for (SQLiteTableScript iTableScript : iTableScripts) {
				ddl = iTableScript.getUpgradeScript(oldVersion, newVersion);
				
				if (ddl != null) {
					for (String sql : ddl) {
						if (!StringUtil.isNullOrWhiteSpace(sql)) {
							Logger.d(TAG, sql);
							db.execSQL(sql);
						}
					}
				}

				dml = iTableScript.getMigrationScript(db, oldVersion, newVersion, null);
				if (dml != null) {
					for (String sql : dml) {
						if (!StringUtil.isNullOrWhiteSpace(sql)) {
							Logger.d(TAG, sql);
							db.execSQL(sql);
						}
					}
				}
			}
			
			db.setTransactionSuccessful();	//	commit
			createFailed = false;
		} catch (Exception e) {
			Logger.e(TAG, e);
			lastError = e;
			createFailed = true;
		} finally {
			db.endTransaction();
		}
	}
}
