package com.ffii.core.utils.sql;

import java.util.Map;

import com.ffii.core.utils.StringUtils;

/**
 * <p>a query builder for handling paging </p>
 * <p><b>suffix cannot blank</b></p>
 * <p>
 * paging arguments key:
 * "start": integer (base at 0),
 * "limit": integer
 * </p>
 * 
 * @see #setPaging(boolean)
 * @see #setPrefix(String)
 * @see #setSuffix(String)
 * 
 * @@author Fung
 */
public class QueryBuilder implements java.io.Serializable {
    private static final long serialVersionUID = 4433680400177304974L;

    // setting
    private boolean paging = false;
    private Map<String, Object> args;

    /** "SELECT *" */
    private String prefix;

    /** "FROM xxxxxxx WHERE true" */
    private String suffix;

    /** default disable paging */
    public QueryBuilder(){}
    public QueryBuilder(boolean paging){
        this.paging = paging;
    }
    
    @Override
    public String toString() {
        return getSearchSql();
    }

    public String getSearchSql() {
        parameterCheck();
        return getPrefix() + " " + getSuffix() + (this.paging ? limitQuery() : "");
    }

    /** column name "count" */
    public String getTotalSql() {
        parameterCheck();
        return "SELECT COUNT(1) 'count'" + " " + getSuffix();
    }

    private void parameterCheck() {
        if (StringUtils.isBlank(suffix))
            throw new IllegalArgumentException("suffix of sql cannot blank");
    }

    private String limitQuery() {
        if (args == null)
            return StringUtils.EMPTY;
        else if (args.containsKey("start") && args.containsKey("limit"))
            return " LIMIT :start,:limit";
        else if (args.containsKey("limit"))
            return " LIMIT :limit";
        else
            return StringUtils.EMPTY;
    }

    // setter and getter

    public boolean isPaging() {
        return this.paging;
    }

    public boolean getPaging() {
        return this.paging;
    }

    /** true for paging query, default false*/
    public void setPaging(boolean paging) {
        this.paging = paging;
    }

    public Map<String, Object> getArgs() {
        return this.args;
    }

    public void setArgs(Map<String, Object> args) {
        this.args = args;
    }

    public String getPrefix() {
        return StringUtils.isNotBlank(this.prefix) ? this.prefix : "SELECT *";
    }

    /** "SELECT *" */
    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public String getSuffix() {
        return this.suffix;
    }

    /** <p>"FROM xxxxxxxx WHERE true"</p>suffix cannot blank*/
    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }

}