package org.beetl.sql.core.db;

import org.beetl.sql.annotation.entity.AssignID;
import org.beetl.sql.annotation.entity.AutoID;
import org.beetl.sql.annotation.entity.SeqID;
import org.beetl.sql.clazz.TableDesc;
import org.beetl.sql.clazz.kit.BeanKit;
import org.beetl.sql.core.range.RangeSql;

import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Map;

/**
 * 数据库差异：db数据库，beetlsql3暂时不能用
 *
 * @author xiandafu
 */
public class DB2SqlStyle extends AbstractDBStyle {

    DB2Range db2Range = null;
    public DB2SqlStyle() {
        db2Range = new DB2Range(this);
    }


    @Override
    public int getIdType(Class c, String idProperty) {
        List<Annotation> ans = BeanKit.getAllAnnotation(c, idProperty);
        int idType = DBType.ID_AUTO; //默认是自增长

        for (Annotation an : ans) {
            if (an instanceof AutoID) {
                idType = DBType.ID_AUTO;
                break;// 优先
            } else if (an instanceof SeqID) {
            	 	idType = DBType.ID_SEQ;
            	 	break;
            } else if (an instanceof AssignID) {
                idType = DBType.ID_ASSIGN;
                break;
            }
        }

        return idType;

    }

    @Override
    public String getName() {
        return "db2";
    }

    @Override
    public int getDBType() {
        return DBType.DB_DB2;
    }

    @Override
    public RangeSql getRangeSql() {
        return null;
    }

    //IBM驱动对插入null 严格遵守了jdbc规范，需要指定类型，参考BeanProcessor.setPreparedStatementPara
//    @Override
    protected String appendSetColumnAbsolute(Class<?> c, TableDesc table, String colName, String fieldName) {
    	int type = table.getColDesc(colName).getSqlType();
        return this.getKeyWordHandler().getCol(colName)  + "=" + appendExpress(fieldName+",jdbc='"+type+"'" ) + ",";
    }
//    @Override
    protected String appendInsertValue(Class<?> c, TableDesc table, String fieldName,String col) {
    	int type = table.getColDesc(col).getSqlType();
        return appendExpress( fieldName +",jdbc='"+ type+"'") + ",";

    }
    
    @Override
    public String getSeqValue(String seqName) {
		return "NEXT VALUE FOR "+ seqName+" ";
	}

	static class DB2Range implements RangeSql{
        DB2SqlStyle style;
        public DB2Range(DB2SqlStyle style){
            this.style = style;
        }

        @Override
        public String toRange(String jdbcSql, Object objOffset, Long limit) {
            Long offset = (Long)objOffset;
            offset = PageParamKit.db2sqlOffset(style.offsetStartZero, offset);
            long pageEnd = PageParamKit.db2sqlPageEnd(offset, limit);
            int capacity = jdbcSql.length() + 180;
            StringBuilder builder = new StringBuilder(capacity);
            builder.append(" SELECT * FROM ").append("(");
            builder.append("	SELECT inner_query_b.*, ROWNUMBER() OVER() beetl_rn  FROM   ");
            builder.append("	(   ").append(jdbcSql).append("	) AS inner_query_b  ");
            builder.append(" )AS inner_query_a WHERE inner_query_a.beetl_rn BETWEEN ");
            builder.append(offset).append(" and ").append(pageEnd);

            return builder.toString();
        }

        @Override
        public String toTemplateRange(Class mapping,String template) {
            return " SELECT * FROM "
                    + "("
                    + "	SELECT inner_query_b.*, ROWNUMBER() OVER() beetl_rn  FROM   "
                    + "	(   "
                    + template + style.getOrderBy()
                    + "	) AS inner_query_b  "
                    + " )AS inner_query_a WHERE inner_query_a.beetl_rn BETWEEN " + style.appendExpress( DBAutoGeneratedSql.OFFSET ) + " and " + style.appendExpress( DBAutoGeneratedSql.PAGE_END);

        }

        @Override
        public void addTemplateRangeParas(Map<String, Object> paras, Object objOffset, long size) {
            Long offset = (Long)objOffset;
            long s = offset + (style.offsetStartZero ? 1 : 0);
            paras.put(DBAutoGeneratedSql.OFFSET, s);
            paras.put(DBAutoGeneratedSql.PAGE_END, s + size - 1);
        }
    }

}
