/**
 * Copyright (c) 2003-2004 System Integrator Corporation.
 *                 All Rights Reserved.
 */
package jp.co.sint.basic;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.naming.NamingException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import jp.co.sint.beans.mallmgr.UIOrderBasic;
import jp.co.sint.config.SIConfig;
import jp.co.sint.config.SIDBMultiConf;// 7.2.0 ST1018 追加
import jp.co.sint.config.SIFlagConf;
import jp.co.sint.database.SIDBAccessException;
import jp.co.sint.database.SIDBUtil;
import jp.co.sint.database.SIDatabaseConnection;
import jp.co.sint.database.SIDuplicateKeyException;
import jp.co.sint.database.SIInsertRec;
import jp.co.sint.database.SIModifyRec;
import jp.co.sint.database.SISpcType;
import jp.co.sint.tools.SIDateTime;
import jp.co.sint.tools.SIFatalException;
import jp.co.sint.tools.SIHTMLUtil;
import jp.co.sint.tools.SIMismatchException;
import jp.co.sint.tools.SIURLMap;
import jp.co.sint.tools.SIUtil;
import jp.co.sint.tools.SIBGUtil;// 7.3.0 PI-NES0501 追加

import org.apache.log4j.Category;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @version $Id: SILoginSession.java,v 1.0 2013/05/20 Exp $
 * Description:
 * <p>
 * History
 * </p>
 * <p>
 * Author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reason
 * </p>
 * ============&nbsp;&nbsp;&nbsp;==========&nbsp;&nbsp;===========================<br>
 * 
 */
public class SILoginSession extends SIBasic {
  
  // ログ用のインスタンスの生成
  private static Category log = Category.getInstance(SIConfig.SILOG4J_WEBSHOP_CATEGORY_NAME);
  
  // セッションID
  private String sessionID = "";
  
  // 顧客コード
  private String custCode = "";
  
  // アクセス日時
  private String accessDate = "";
  
  // 登録日時
  private String createDate = "";
  
  // 削除フラグ
  private String delFlg = "0";
  
  public SILoginSession() {}
  
  public SILoginSession(String lSessionId) {
    setSessionId(lSessionId);
  }
  
  // setter of セッションID
  public void setSessionId(String lSessionId) {
    if (SIUtil.isNull(lSessionId)) lSessionId = "";
    this.sessionID = SIUtil.changeTo(lSessionId.trim(), this.encode);
  }
  
  // setter of 顧客コード
  public void setCustCode(String lCustCode) {
    this.custCode = SIUtil.changeTo(lCustCode, this.encode);
  }
  
  // setter of アクセス日時
  public void setAccessDate(String lAccessDate) {
    if (SIUtil.isNull(lAccessDate)) lAccessDate = "";
    this.accessDate = SIUtil.changeTo(lAccessDate.trim(), this.encode);
  }
  
  // setter of 登録日時
  public void setCreateDate(String lCreateDate) {
    if (SIUtil.isNull(lCreateDate)) lCreateDate = "";
    this.createDate = SIUtil.changeTo(lCreateDate.trim(), this.encode);
  }
  
  // setter of 削除フラグ
  public void setDelFlg(String lDelFlg) {
    if (SIUtil.isNull(lDelFlg)) lDelFlg = "0";
    this.delFlg = SIUtil.changeTo(lDelFlg.trim(), this.encode);
  }
  
  public String getSessionId(){
    return this.sessionID;
  }
  
  /**
   * クッキーからセッションID返却
   * @param lRequest
   * @return
   */
  public static String getSessionId(HttpServletRequest lRequest){
    String sid = "";
    Cookie[] cookies = lRequest.getCookies();

    for (int i = 0; cookies != null && i < cookies.length; i++) {
      // クッキーの名前で判別
      if (cookies[i].getName().equals(SIConfig.SICOOKIE_LOGIN)) {
        sid = cookies[i].getValue();
        break;
      }
    }

    return sid;
  }
  
  public String getCustCode(){
    return this.custCode;
  }
  
  public String getAccessDate(){
    return this.accessDate;
  }
  
  public String getCreateDate(){
    return this.createDate;
  }
  
  /**
   * <b>checkSession</b> セッションの有効性をチェックします
   * 
   * @param lRequest
   */
  public static String checkSession(HttpServletRequest lRequest) {
    //HttpSession session = lRequest.getSession(true);// セッションの取得
    SIDatabaseConnection databaseConnection = new SIDatabaseConnection();// DBへのコネクションの作成

    String sid = getSessionId(lRequest);
    if (sid == "") return sid;

    try {
      Connection lConnection = databaseConnection.getConnection();
      String accessdate = "";
      accessdate = SIDBUtil.getFirstData(lConnection, "SELECT accessdate FROM loginsessiontbl WHERE sessionid="+SIDBUtil.SQL2Str(sid) + " AND delflg = 0");
      if (SIUtil.isNull(accessdate)) return "";
      
      // 現在日時を取得
      Calendar cal = Calendar.getInstance();
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy'-'MM'-'dd' 'HH':'mm':'ss");
      // 1時間前
      cal.add(Calendar.MONTH, -1);
      String dateString = sdf.format(cal.getTime());
      if(dateString.compareTo(accessdate) > 0){
          // 削除フラグをたてる
          SIModifyRec lRec = new SIModifyRec("LOGINSESSIONTBL");
          lRec.addCondition("sessionid", sid);
          lRec.add("delflg", 1);
          try {
            lRec.execute(lConnection);
            lConnection.commit();
          } catch (SIDuplicateKeyException e) {
            e.printStackTrace();
          }
          
          return "";
      }
      
    } catch (SQLException e) {
      e.printStackTrace();
    } catch (NamingException e) {
      e.printStackTrace();
    } catch (SIDBAccessException e) {
      e.printStackTrace();
    } finally {
      databaseConnection.close();
    }
    
    return sid;
  }
  
  public void save(Connection lConnection) throws SIDuplicateKeyException, SIDBAccessException {     
      SIInsertRec lRec = new SIInsertRec("LOGINSESSIONTBL");
      lRec.add("sessionid", this.getSessionId());
      lRec.add("custcode", this.getCustCode());
      lRec.add("accessdate", new SISpcType("TO_CHAR(now(),'YYYY/MM/DD HH24:MI:SS')::timestamp"));
      lRec.add("createdate", new SISpcType("TO_CHAR(now(),'YYYY/MM/DD HH24:MI:SS')::timestamp"));
      lRec.add("delflg", 0);
      // 登録
      lRec.execute(lConnection);
  }

  /**
   * ハッシュ値を返す
   * @param org 計算元文字列
   * @param algorithm ハッシュアルゴリズム名
   * @return ハッシュ値
   */
  public static String getHash(String org, String algorithm){
      // 引数・アルゴリズム指定が無い場合は計算しない
      if ((org== null)||(algorithm== null)){
          return null;
      }
      
      // 初期化
      MessageDigest md= null;
      try{
          md= MessageDigest.getInstance(algorithm);
      }
      catch(NoSuchAlgorithmException e){
          return null;
      }
      
      md.reset();
      md.update(org.getBytes());
      byte[] hash= md.digest();
      
      // ハッシュを16進数文字列に変換
      StringBuffer sb= new StringBuffer();
      int cnt= hash.length;
      for(int i= 0; i< cnt; i++){
          sb.append(Integer.toHexString( (hash[i]>> 4) & 0x0F ) );
          sb.append(Integer.toHexString( hash[i] & 0x0F ) );
      }
      return sb.toString();
  }

}