/*
 * Copyright (c) 2007, Going Dot Com Inc. All rights reserved.
 */

package jp.co.going.xbrl.taxonomy;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

import jp.co.going.xbrl.common.XbException;

/**
 * 派生した型をＤＢに登録するクラス
 * 
 * @author Going Dot Com Inc.
 */
class XbItemTypeDAO {

    // singleton作成
    private static XbItemTypeDAO taxGrp = null;
    // Connection変数
    private static Connection conn = null;
    // ステートメント
    private PreparedStatement stmt;

    // コンストラクタ
    private XbItemTypeDAO() {
    }

    // インスタンス取得
    protected static synchronized XbItemTypeDAO getInstance(Connection connection) {
        // インスタンスを生成
        if (taxGrp == null) {
            conn = connection;
            taxGrp = new XbItemTypeDAO();
        }

        return taxGrp;
    }

	private int getCount(String strTypeName, String strVerSion) throws XbException {
        try {
            StringBuffer  strb_sql = new StringBuffer();
    		// メインリスト
    		int relist = 0;
    		strb_sql.append("select ");
    		strb_sql.append("type_name, ");
    		strb_sql.append("attribute_name, ");
    		strb_sql.append("specification_no, ");
    		strb_sql.append("creation_date ");
    		strb_sql.append("from xb_item_type ");
    		strb_sql.append("where type_name = ? ");
    		strb_sql.append("and specification_no = ?");
    		// SQL設定
    		stmt = conn.prepareStatement(strb_sql.toString());
    		int index = 1;
    		stmt.setString(index++, strTypeName);
    		stmt.setString(index++, strVerSion);

    		ResultSet rs = stmt.executeQuery();
    		if (rs.next()) {
                relist ++;
            }
    	    // 結果セットをクローズ
    	    rs.close();
    	    // ステートメントをクローズ
    	    stmt.close();

    	    return relist;
        } catch (SQLException e) {
            throw new XbException(e, "SQLError : " + e.getMessage());
        }
	}

	private String getContextType(String strTypeName, String strVerSion) throws XbException {
        try {
            StringBuffer  strb_sql = new StringBuffer();
            // メインリスト
            String type = "";
            strb_sql.append("select ");
            strb_sql.append("attribute_name ");
            strb_sql.append("from xb_item_type ");
            strb_sql.append("where type_name = ? ");
            strb_sql.append("and specification_no = ?");
            // SQL設定
            stmt = conn.prepareStatement(strb_sql.toString());
            int index = 1;
            stmt.setString(index++, strTypeName);
            stmt.setString(index++, strVerSion);

            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                type = rs.getString("attribute_name");
                rs.close();
                stmt.close();
            } else {
                rs.close();
                stmt.close();
                throw new XbException("選択したバージョンに存在しない型が定義されています。");
            }

            return type;
        } catch (SQLException e) {
            throw new XbException(e, "SQLError : " + e.getMessage());
        }
    }

    protected void insert(String name, String type, String spec, Date date) throws XbException {
        try {
            // 重複チェック
            int count = this.getCount(name, spec);
            // item登録
            if (count == 0) {
                // contextType取得
                String contextType = this.getContextType(type, spec);

                StringBuffer  strb_sql = new StringBuffer();
                // 問合せの実行
                strb_sql.append("insert into ");
                strb_sql.append("xb_item_type ");
                strb_sql.append("values ");
                strb_sql.append("(?, ?, ?, ?)");
                // SQL設定
                stmt = conn.prepareStatement(strb_sql.toString());
                int index = 1;
                stmt.setString(index ++, name);
                stmt.setString(index ++, contextType);
                stmt.setString(index ++, spec);
                stmt.setTimestamp(index ++, new java.sql.Timestamp(date.getTime()));
                // SQL　実行
                stmt.executeUpdate();
                // ステートメントをクローズ
                stmt.close();
            }
        } catch (SQLException e) {
            throw new XbException(e, "SQLError : " + e.getMessage());
        }
    }
}