package com.engine.kq.log;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.UUID;
import org.apache.log4j.Level;
import weaver.common.DateUtil;
import weaver.conn.ConnStatement;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.common.DbFunctionUtil;

/**
 * 考勤日志记录
 */
public class KQLog extends BaseBean {

  private static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger("hrmkq");

  /**
   * 是否记录日志
   */
  private boolean isLog = true;

  public KQLog() {
    String hrmkqlogOpen = Util.null2s(getPropValue("hrmkqlog", "hrmkqlogOpen"),"true");
    if("true".equalsIgnoreCase(hrmkqlogOpen)){
      isLog = true;
    }else{
      isLog = false;
    }
  }

  public void debug(Object message) {
    if(isLog){
      String msg = getLogMsg();
      log.debug(msg+message);
    }
  }

  public void debug(Object message, Throwable exception) {
    if(isLog){
      String msg = getLogMsg();
      log.debug(msg+message, exception);
    }
  }

  public void info(Object message) {
    if(isLog){
      String msg = getLogMsg();
      log.info(Thread.currentThread().getName()+":"+msg+message);
    }
  }

  public void info(Object message, Throwable exception) {
    if(isLog){
      String msg = getLogMsg();
      log.info(msg+message, exception);
    }
  }

  public void warn(Object message) {
    if(isLog){
      String msg = getLogMsg();
      log.warn(msg+message);
    }
  }

  public void warn(Object message, Throwable exception) {
    if(isLog){
      String msg = getLogMsg();
      log.warn(msg+message, exception);
    }
  }

  public void error(Object message) {
    if(isLog){
      String msg = getLogMsg();
      log.error(msg+message);
    }
  }

  public void error(Object message, Throwable exception) {
    if(isLog){
      String msg = getLogMsg();
      log.error(msg+message, exception);
    }
  }

  @Override
  public void writeLog(String classname , Object obj)  {
    if(isLog){
      if(obj instanceof Exception){
        log.error(classname ,(Exception)obj);
      }else if(obj instanceof String){
        String msg = getLogMsg();
        log.error(msg+obj);
      }else{
        log.error(obj);
      }
    }
  }

  private String getLogMsg(){
    StackTraceElement[] arr =  Thread.currentThread().getStackTrace();
    int index = arr.length-1;
    boolean flag = false;
    for(int i=0;i<arr.length;i++){
      StackTraceElement obj = arr[i];
      if(obj.getClassName().equals("com.engine.kq.log.KQLog")&&obj.getMethodName().equals("getLogMsg")){
        index = i;
        flag = true;
        continue;
      }else if(obj.getClassName().equals("com.engine.kq.log.KQLog")){
        continue;
      }else if(obj.getMethodName().equals("writeLog")){
        continue;
      }else if(flag){
        index = i;
        break;
      }

    }
    String msg = "";
    if(arr.length>index){
      int line = Thread.currentThread().getStackTrace()[index].getLineNumber();
      String method = Thread.currentThread().getStackTrace()[index].getMethodName();
      String classname = Thread.currentThread().getStackTrace()[index].getClassName();
      msg = classname+"."+method+"() - line:"+line+" : ";
//      String curDateTime = DateUtil.getFullDate();
//      String tmpDateTime = DateUtil.getCurrentDate()+" 09:00:00";
//      if(curDateTime.compareTo(tmpDateTime) < 0){
//        StringWriter errorsWriter = new StringWriter();
//        new Exception().printStackTrace(new PrintWriter(errorsWriter));
//        msg = errorsWriter.toString();
//      }
    }
    return msg;
  }

  @Override
  public void writeLog(Object obj) {
    writeLog(getClass().getName(),obj);
  }

  public static void setLogLevel(String levle){
    //日志级别优先级：OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL
    if("DEBUG".equals(levle)){
      log.setLevel(Level.DEBUG);
    }else if("INFO".equals(levle)){
      log.setLevel(Level.INFO);
    }else if("WARN".equals(levle)){
      log.setLevel(Level.WARN);
    }else if("ERROR".equals(levle)){
      log.setLevel(Level.ERROR);
    }
  }

  public static String getLogLevel(){
    //日志级别优先级：OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL
    return log.getLevel().toString();
  }

  public boolean isLog() {
    return isLog;
  }

  public void setLog(boolean log) {
    isLog = log;
  }

  /**
   * 希望实现每次考勤相关操作的时候都可以记录下当时的考勤信息
   * @param resourceid
   * @param groupshift_info
   */
  public void log_kqchangeinfo(String resourceid,String groupshift_info){
    if(resourceid.length() == 0){
      return;
    }
    String uuid = UUID.randomUUID().toString();
    RecordSet rs = new RecordSet();

    boolean isok = false;
    if(rs.getDBType().equalsIgnoreCase("oracle")&&Util.null2String(rs.getOrgindbtype()).equals("oracle")){
      String sql = "insert into kq_groupshift_changeinfo(resourceid,changedatetime,groupshift_info,uuid) "
          + " values("+resourceid+","+DbFunctionUtil.getCurrentFullTimeFunction(rs.getDBType())+",empty_clob(),'"+uuid+"') ";
      isok = rs.executeUpdate(sql);
    }else{
      String sql = "insert into kq_groupshift_changeinfo(resourceid,changedatetime,groupshift_info,uuid) "
          + " values("+resourceid+","+DbFunctionUtil.getCurrentFullTimeFunction(rs.getDBType())+",'"+groupshift_info+"','"+uuid+"') ";

      rs.executeUpdate(sql);
    }

    if(isok && rs.getDBType().equalsIgnoreCase("oracle")&&Util.null2String(rs.getOrgindbtype()).equals("oracle")){
      ConnStatement stat=null;
      try {
        stat = new ConnStatement();
        // 需要使用for update方法来进行更新，
        // 但是，特别需要注意，如果原来CLOB字段有值，需要使用empty_clob()将其清空。
        // 如果原来是null，也不能更新，必须是empty_clob()返回的结果。
        stat.setStatementSql("select groupshift_info from kq_groupshift_changeinfo where uuid=? for update", false);
        stat.setString(1,uuid);
        stat.executeQuery();
        if (stat.next()) {
          oracle.sql.CLOB clob = (oracle.sql.CLOB) stat.getClob("groupshift_info");
          Writer outStream = clob.getCharacterOutputStream();
          char[] c = groupshift_info.toCharArray();
          outStream.write(c, 0, c.length);
          outStream.flush();
          outStream.close();
        }

      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        if (stat != null) {
          stat.close();
        }
      }
    }

  }
}
