/**
 *
 */
package control;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import model.Account;
import model.ClassAccount;
import system.ClassColumnMaster;
import system.ClassColumnSetting;
import system.ClassPerson;
import system.ColumnMaster;

import common.DBAccessWrapper;
import common.Environment;
import common.XSVReader;

/**
 *
 * @author 無糖ブラック
 *
 */
public class Maintenance extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		String characterEncoding = "UTF-8";
		request.setCharacterEncoding(characterEncoding);

		String contentType = "text/html; charset=UTF-8";
		response.setContentType(contentType);

		String envPath = getServletContext().getRealPath("/conf/env.ini");
		Environment env = Environment.getEnvironment();
		env.init(envPath);

		HttpSession session = request.getSession(false);

		String in_userid = (String)session.getAttribute("userid");
		if ( in_userid.equals("") ) {
			return;
		}

		String in_option = request.getParameter("option");
		if ( in_option.equals("") ) {
			return;
		}

		//ユーザー情報初期化
		if ( in_option.equals("setupPerson") ) {
			String messageString = setupPerson(in_userid);

			//登録結果出力
			response.getWriter().write(messageString);
		}
		else if ( in_option.equals("setupColumns") ) {
			String messageString = setupColumns(in_userid);

			//登録結果出力
			response.getWriter().write(messageString);
		}
		else if ( in_option.equals("setupAccount") ) {
			String messageString = setupAccount(in_userid);

			//登録結果出力
			response.getWriter().write(messageString);
		}
	}

	/**
	 * ユーザー情報初期化
	 * @return
	 */
	private String setupPerson(String in_userid) {

		String messageString = "";
		int result = 0;
		Environment env = Environment.getEnvironment();
		DBAccessWrapper db = new DBAccessWrapper(env);
		ClassPerson clsPerson = new ClassPerson(db);

		try {
			db.connect();
			db.startTransaction();

			//ユーザーテーブル初期化
			result = clsPerson.truncate();
			if ( result < 0 ) {
				db.rollback();
				db.close();
				return "ユーザー情報の初期化に失敗しました。";
			}

			ArrayList<String> insertParams = new ArrayList<String>();
			ArrayList<String> insertTypes  = new ArrayList<String>();
			ArrayList<Object> insertValues  = new ArrayList<Object>();

			insertParams.clear();
			insertParams.add("PERSON_NUMBER");
			insertParams.add("PASSWORD");
			insertParams.add("NAME");
			insertParams.add("CREATE_PERSON");
			insertParams.add("MODIFY_PERSON");

			insertTypes .clear();
			insertTypes .add("string");
			insertTypes .add("string");
			insertTypes .add("string");
			insertTypes .add("string");
			insertTypes .add("string");

			insertValues .clear();
			insertValues .add(in_userid);
			insertValues .add(in_userid);
			insertValues .add(in_userid);
			insertValues .add(in_userid);
			insertValues .add(in_userid);

			clsPerson.create(insertParams, insertTypes , insertValues);

			db.commit();
			db.close();

			messageString = "ユーザー情報を初期化しました。";
		} catch (SQLException e) {
			e.printStackTrace();
			try {
				db.rollback();
				db.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			messageString = "ユーザー情報の初期化に失敗しました。";
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			try {
				db.rollback();
				db.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			messageString = "ユーザー情報の初期化に失敗しました。";
		}

		return messageString;
	}

	/**
	 * 列情報初期化
	 * @return
	 */
	private String setupColumns(String in_userid) {

		//列情報初期設定ファイル読み込み
		String path = getServletContext().getRealPath("/conf/columns.ini");
		XSVReader xsvReader = new XSVReader(path, "\t");
		ArrayList<String[]> lines;
		try {
			lines = xsvReader.readLines();
		} catch (IOException e) {
			e.printStackTrace();
			return "列情報初期設定ファイル読み込みに失敗しました。";
		}

		String messageString = "";
		int result = 0;
		Environment env = Environment.getEnvironment();
		DBAccessWrapper db = new DBAccessWrapper(env);

		ClassColumnMaster clsColumnMaster = new ClassColumnMaster(db);
		ClassColumnSetting clsColumnSetting = new ClassColumnSetting(db);

		try {
			db.connect();
			db.startTransaction();

			//列情報テーブル初期化
			result = clsColumnMaster.truncate();
			if ( result < 0 ) {
				db.rollback();
				db.close();
				return "列情報の初期化に失敗しました。";
			}

			ArrayList<String> insertParams1 = new ArrayList<String>();
			ArrayList<String> insertTypes1  = new ArrayList<String>();
			ArrayList<Object> insertValues1  = new ArrayList<Object>();

			insertParams1.clear();
			insertParams1.add("TABLE_VIEW_NAME");
			insertParams1.add("TABLE_ID");
			insertParams1.add("COLUMN_VIEW_NAME");
			insertParams1.add("COLUMN_ID");
			insertParams1.add("COLUMN_TYPE");
			insertParams1.add("COLUMN_LENGTH");
			insertParams1.add("CREATE_PERSON");
			insertParams1.add("MODIFY_PERSON");

			insertTypes1.clear();
			insertTypes1.add("string");
			insertTypes1.add("string");
			insertTypes1.add("string");
			insertTypes1.add("string");
			insertTypes1.add("string");
			insertTypes1.add("int");
			insertTypes1.add("string");
			insertTypes1.add("string");

			ArrayList<String> insertParams2 = new ArrayList<String>();
			ArrayList<String> insertTypes2  = new ArrayList<String>();
			ArrayList<Object> insertValues2  = new ArrayList<Object>();

			insertParams2.clear();
			insertParams2.add("SUPER_IDENTIFICATION");
			insertParams2.add("USER_NUMBER");
			insertParams2.add("DISPLAY");
			insertParams2.add("STRUCT_ORDER");
			insertParams2.add("WITDH");
			insertParams2.add("CREATE_PERSON");
			insertParams2.add("MODIFY_PERSON");

			insertTypes2.clear();
			insertTypes2.add("int");
			insertTypes2.add("string");
			insertTypes2.add("boolean");
			insertTypes2.add("int");
			insertTypes2.add("int");
			insertTypes2.add("string");
			insertTypes2.add("string");

			String lastTableName = "";
			int structOrder = 1;
			for( int ii = 1; ii < lines.size(); ++ii ) {

				String[] attrs = lines.get(ii);

				String tableViewName = "";
				String tableName = "";
				String columnViewName = "";
				String columnName = "";
				String columnType = "";
				String columnLength = "";

				for (int jj = 0; jj < attrs.length; ++jj ) {
					switch (jj) {
					case 0:
						tableViewName = attrs[0];
						break;
					case 1:
						tableName = attrs[1];
						break;
					case 2:
						columnViewName = attrs[2];
						break;
					case 3:
						columnName = attrs[3];
						break;
					case 4:
						columnType = attrs[4];
						break;
					case 5:
						columnLength = attrs[5];
						break;
					}
				}

				//列情報登録
				insertValues1.clear();
				insertValues1.add(tableViewName);
				insertValues1.add(tableName);
				insertValues1.add(columnViewName);
				insertValues1.add(columnName);
				insertValues1.add(columnType);
				insertValues1.add(columnLength);
				insertValues1.add(in_userid);
				insertValues1.add(in_userid);

				ColumnMaster columnMaster = clsColumnMaster.create(insertParams1, insertTypes1 , insertValues1);

				//列情報登録
				insertValues2.clear();
				insertValues2.add(columnMaster.identification());
				insertValues2.add(in_userid);
				insertValues2.add("true");
				insertValues2.add(structOrder);
				insertValues2.add("200");
				insertValues2.add(in_userid);
				insertValues2.add(in_userid);

				clsColumnSetting.create(insertParams2, insertTypes2, insertValues2);

				if ( lastTableName.isEmpty() || !lastTableName.equals(tableName) ) {
					lastTableName = tableName;
					structOrder = 1;
				}
				else {
					++structOrder;
				}
			}

			db.commit();
			db.close();

			messageString = "列情報を初期化しました。";
		} catch (SQLException e) {
			e.printStackTrace();
			try {
				db.rollback();
				db.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			messageString =  "列情報の初期化に失敗しました。";
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			try {
				db.rollback();
				db.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			messageString =  "列情報の初期化に失敗しました。";
		}

		return messageString;
	}

	/**
	 * 勘定科目初期化
	 * @param in_userid
	 * @return
	 * @throws IOException
	 */
	private String setupAccount(String in_userid) {

		//勘定科目初期設定ファイル読み込み
		String path = getServletContext().getRealPath("/conf/account.ini");
		XSVReader xsvReader = new XSVReader(path, "\t");
		ArrayList<String[]> lines;
		try {
			lines = xsvReader.readLines();
		} catch (IOException e) {
			e.printStackTrace();
			return "勘定科目初期設定ファイル読み込みに失敗しました。";
		}

		String messageString = "";
		int result = 0;
		Environment env = Environment.getEnvironment();
		DBAccessWrapper db = new DBAccessWrapper(env);
		ClassAccount clsAccount = new ClassAccount(db);

		try {
			db.connect();
			db.startTransaction();

			//勘定科目テーブル初期化
			result = clsAccount.truncate();
			if ( result < 0 ) {
				db.rollback();
				db.close();
				return "勘定科目の初期化に失敗しました。";
			}

			ArrayList<String> insertParams = new ArrayList<String>();
			ArrayList<String> insertTypes  = new ArrayList<String>();
			ArrayList<Object> insertValues  = new ArrayList<Object>();

			insertParams.clear();
			insertParams.add("ACCOUNT_NUMBER");
			insertParams.add("NAME");
			insertParams.add("AMOUNT");
			insertParams.add("CONSUMPTION_TAX_RATE");
			insertParams.add("ACCOUNT_TYPE");
			insertParams.add("DEBIT_CREDIT_TYPE");
			insertParams.add("BP_TYPE");
			insertParams.add("DEPARTMENT_NUMBER");
			insertParams.add("DISPLAY");
			insertParams.add("SYSTEM_FLAG");
			insertParams.add("CREATE_PERSON");
			insertParams.add("MODIFY_PERSON");

			insertTypes .clear();
			insertTypes .add("string");
			insertTypes .add("string");
			insertTypes .add("int");
			insertTypes .add("int");
			insertTypes .add("string");
			insertTypes .add("string");
			insertTypes .add("string");
			insertTypes .add("string");
			insertTypes .add("boolean");
			insertTypes .add("boolean");
			insertTypes .add("string");
			insertTypes .add("string");

			for( int ii = 0; ii < lines.size(); ++ii ) {

				//勘定科目登録
				String[] attrs = lines.get(ii);

				//勘定科目登録
				insertValues .clear();
				insertValues .add(attrs[0]);
				insertValues .add(attrs[1]);
				insertValues .add(attrs[2]);
				insertValues .add(attrs[3]);
				insertValues .add(attrs[4]);
				insertValues .add(attrs[5]);
				insertValues .add(attrs[6]);
				insertValues .add(attrs[7]);
				insertValues .add(attrs[8]);
				insertValues .add(attrs[9]);
				insertValues .add(in_userid);
				insertValues .add(in_userid);

				Account account;
				account = clsAccount.create(insertParams, insertTypes , insertValues);

				String accountIdentification;
				accountIdentification = account.identification();
				if ( accountIdentification.equals("") ) {
					db.rollback();
					db.close();
					return "勘定科目の登録に失敗しました。";
				}

				if ( attrs.length > 10 ) {
					//上位勘定科目検索
					String condition = "ACCOUNT_NUMBER = ?";
					ArrayList<String> conditionTypes = new ArrayList<String>();
					ArrayList<Object> conditionValues = new ArrayList<Object>();
					conditionTypes.add("string");
					conditionValues.add(attrs[10]);

					//勘定科目構成登録
					ArrayList<Account> results;
					results = clsAccount.select(condition, conditionTypes, conditionValues);
					Account parentAccount = results.get(0);
					parentAccount.appendChild(account, in_userid);
				}
			}

			db.commit();
			db.close();

			messageString = "勘定科目を初期化しました。";
		} catch (SQLException e) {
			e.printStackTrace();
			try {
				db.rollback();
				db.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			messageString = "勘定科目の初期化に失敗しました。";
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			try {
				db.rollback();
				db.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			messageString = "勘定科目の初期化に失敗しました。";
		}

		return messageString;
	}
}
