package com.eactive.eai.rms.common.base;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import com.eactive.eai.rms.common.vo.SchemaIdVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.ibatis.SqlMapClientCallback;
import org.springframework.orm.ibatis.SqlMapClientTemplate;

import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.login.LoginVo;
import com.eactive.eai.rms.common.login.SessionManager;
import com.eactive.eai.rms.common.util.CommonConstants;
import com.eactive.kakao.rolling.TableSuffixResolver;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.event.RowHandler;

@SuppressWarnings(value = { "unchecked", "deprecation" })
public class SchemaIdConfiguredSqlMapTemplate extends SqlMapClientTemplate {
    
	Logger logger = Logger.getLogger(SchemaIdConfiguredSqlMapTemplate.class);
	
	private TableSuffixResolver tableSuffixResolver;

	protected Object addParameterObject(String statementName, Object parameterObject) {

		if (parameterObject instanceof Map) {
			Map<String, Object> paramMap = (Map<String, Object>) parameterObject;

			if (paramMap.get(CommonConstants.schemaId_KEY) == null) {
				paramMap.put(CommonConstants.schemaId_KEY, DataSourceContextHolder.getDataSourceType().getSchema());
			}
			// login user °ü·Ã
			if (paramMap.get(CommonConstants.loginId_KEY) == null) {
				LoginVo loginVo = SessionManager.getLoginVo();
				if (loginVo != null) {
					paramMap.put(CommonConstants.loginId_KEY, loginVo.getUserId());
				}
			}

            if (paramMap.get("rollingSuffix") == null && DataSourceContextHolder.getDataSourceType().isOnline()) {
                String rollingSuffix = tableSuffixResolver.getCurrentSuffix();
                paramMap.put(CommonConstants.ROLLING_SUFFIX, rollingSuffix);
            }
			
			if (logger.isDebugEnabled()) {

				StringBuilder sb = new StringBuilder();
				sb.append("Statement Name : " + statementName).append("\n");
				for (Iterator<String> it = paramMap.keySet().iterator(); it.hasNext();) {

					String key = it.next();
					sb.append(key + "=" + paramMap.get(key)).append(", ");
				}
				logger.debug("SQLMap Parameters : " + sb.toString());
			}
			return paramMap;
        } else if (parameterObject instanceof SchemaIdVO) {
            SchemaIdVO schemaIdVO = (SchemaIdVO) parameterObject;
            if (StringUtils.isBlank(schemaIdVO.getSchemaId())) {
                schemaIdVO.setSchemaId(DataSourceContextHolder.getDataSourceType().getSchema());
            }
            if (StringUtils.isBlank(schemaIdVO.getLoginId())) {
                LoginVo loginVo = SessionManager.getLoginVo();
                if (loginVo != null) {
                    schemaIdVO.setLoginId(loginVo.getUserId());
                }
            }
        }
		return parameterObject;
	}
	
    

    public SchemaIdConfiguredSqlMapTemplate() {
        super();
    }

    public SchemaIdConfiguredSqlMapTemplate(DataSource dataSource,
            SqlMapClient sqlMapClient) {
        super(dataSource, sqlMapClient);
    }

    public SchemaIdConfiguredSqlMapTemplate(SqlMapClient sqlMapClient) {
        super(sqlMapClient);
    }

	public SchemaIdConfiguredSqlMapTemplate(SqlMapClient sqlMapClient, TableSuffixResolver tableSuffixResolver) {
		super(sqlMapClient);
		this.tableSuffixResolver = tableSuffixResolver;
	}

	@Override
    public void delete(String statementName, Object parameterObject,
            int requiredRowsAffected) throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        super.delete(statementName, parameterObject, requiredRowsAffected);
    }

    @Override
    public int delete(String statementName, Object parameterObject)
            throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.delete(statementName, parameterObject);
    }

    @Override
    public Object insert(String statementName, Object parameterObject)
            throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.insert(statementName, parameterObject);
    }

    @Override
    public List<Map<String, Object>> queryForList(String statementName, int skipResults,
            int maxResults) throws DataAccessException {
    	Object parameterObject = new HashMap<String,Object>();
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.queryForList(statementName, parameterObject, skipResults, maxResults);
    }

    @Override
    public List<Map<String, Object>> queryForList(String statementName, Object parameterObject,
            int skipResults, int maxResults) throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.queryForList(statementName, parameterObject, skipResults,
            maxResults);
    }

    @Override
    public List<Map<String, Object>> queryForList(String statementName, Object parameterObject)
            throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.queryForList(statementName, parameterObject);
    }

    @Override
    public Map<String, Object> queryForMap(String statementName, Object parameterObject,
            String keyProperty, String valueProperty)
            throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.queryForMap(statementName, parameterObject, keyProperty,
            valueProperty);
    }

    @Override
    public Map<String, Object> queryForMap(String statementName, Object parameterObject,
            String keyProperty) throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.queryForMap(statementName, parameterObject, keyProperty);
    }

    @Override
    public Object queryForObject(String statementName, Object parameterObject,
            Object resultObject) throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.queryForObject(statementName, parameterObject,
            resultObject);
    }

    @Override
    public Object queryForObject(String statementName, Object parameterObject)
            throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.queryForObject(statementName, parameterObject);
    }

//    @Override
//    public PaginatedList queryForPaginatedList(String statementName,
//            int pageSize) throws DataAccessException {
//        return super.queryForPaginatedList(statementName, pageSize);
//    }
//
//    @Override
//    public PaginatedList queryForPaginatedList(String statementName,
//            Object parameterObject, int pageSize) throws DataAccessException {
//        return super.queryForPaginatedList(statementName, parameterObject,
//            pageSize);
//    }

    @Override
    public void queryWithRowHandler(String statementName,
            Object parameterObject, RowHandler rowHandler)
            throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        super.queryWithRowHandler(statementName, parameterObject, rowHandler);
    }

    @Override
    public void queryWithRowHandler(String statementName, RowHandler rowHandler)
            throws DataAccessException {
    	Object parameterObject = new HashMap<String,Object>();
    	parameterObject = addParameterObject(statementName, parameterObject);
        super.queryWithRowHandler(statementName, parameterObject, rowHandler);
    }

    @Override
    public int update(String statementName, Object parameterObject)
            throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.update(statementName, parameterObject);
    }

    @Override
    public void update(String statementName, Object parameterObject,
            int requiredRowsAffected) throws DataAccessException {
    	parameterObject = addParameterObject(statementName, parameterObject);
        super.update(statementName, parameterObject, requiredRowsAffected);
    }

    @Override
    public List<Map<String, Object>> queryForList(String statementName) throws DataAccessException {
    	Object parameterObject = new HashMap<String,Object>();
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.queryForList(statementName, parameterObject);
    }

    @Override
    public Object queryForObject(String statementName)
            throws DataAccessException {
    	Object parameterObject = new HashMap<String,Object>();
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.queryForObject(statementName, parameterObject);
    }

    @Override
    public int delete(String statementName) throws DataAccessException {
    	Object parameterObject = new HashMap<String,Object>();
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.delete(statementName, parameterObject);
    }

    @Override
    public Object execute(@SuppressWarnings("rawtypes") SqlMapClientCallback action)
            throws DataAccessException {
//    	Object parameterObject = new HashMap<String,Object>();
//    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.execute(action);
    }

    @Override
    public List<Map<String, Object>> executeWithListResult(@SuppressWarnings("rawtypes") SqlMapClientCallback action)
            throws DataAccessException {
//    	Object parameterObject = new HashMap<String,Object>();
//    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.executeWithListResult(action);
    }

    @Override
    public Map<String, Object> executeWithMapResult(@SuppressWarnings("rawtypes") SqlMapClientCallback action)
            throws DataAccessException {
//    	Object parameterObject = new HashMap<String,Object>();
//    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.executeWithMapResult(action);
    }

    @Override
    public Object insert(String statementName) throws DataAccessException {
    	Object parameterObject = new HashMap<String,Object>();
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.insert(statementName, parameterObject);
    }

    @Override
    public int update(String statementName) throws DataAccessException {
    	Object parameterObject = new HashMap<String,Object>();
    	parameterObject = addParameterObject(statementName, parameterObject);
        return super.update(statementName, parameterObject);
    }

}
