package cn.orm.util.builder.base;

import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;

import cn.orm.util.builder.BuildWhere;
import cn.util.core.IsKit;

public class SQLCondition
{
	private StringBuilder builder;
	
	public SQLCondition whereAttributeTo(String ids)
	{
		builder.append(BuildWhere.genQueryWrapper(ids));
		return this;
	}
	

	/***
	 * Constructor
	 */
	public SQLCondition() {
		builder = new StringBuilder();
	}
	
	/***
	 * Condition first argument
	 * @param attributeName		First argument in condition
	 * @return					(Unfinished) condition
	 */
	public SQLCondition whereAttribute(String attributeName) {
		builder.append(attributeName).append(' ');
		return this;
	}

	/***
	 * Condition first argument
	 * @param attributeName		First argument in condition
	 * @return					(Unfinished) condition
	 */
	public SQLCondition whereAttribute(char attributeName) {
		builder.append(attributeName).append(' ');
		return this;
	}

	/***
	 * Condition first argument
	 * @param attributeName		First argument in condition
	 * @return					(Unfinished) condition
	 */
	public SQLCondition andAttribute(String attributeName) {
		builder.append("AND ").append(attributeName).append(' ');
		return this;
	}

	/***
	 * Condition first argument
	 * @param attributeName		First argument in condition
	 * @return					(Unfinished) condition
	 */
	public SQLCondition andAttribute(char attributeName) {
		builder.append("AND ").append(attributeName).append(' ');
		return this;
	}

	/***
	 * Condition first argument
	 * @param attributeName		First argument in condition
	 * @return					(Unfinished) condition
	 */
	public SQLCondition orAttribute(String attributeName) {
		builder.append("OR ").append(attributeName).append(' ');
		return this;
	}

	/***
	 * Condition first argument
	 * @param attributeName		First argument in condition
	 * @return					(Unfinished) condition
	 */
	public SQLCondition orAttribute(char attributeName) {
		builder.append("OR ").append(attributeName).append(' ');
		return this;
	}

	/***
	 * Condition second argument
	 * @param subquery			Subquery in condition
	 * @return					condition
	 */
	public SQLCondition equalsToSubquery(SQLSubquery subquery) {
		builder.append("= (").append(subquery.create()).append(") ");
		return this;
	}
	public SQLCondition addCondition(String subquery) {
		builder.append(" ").append(subquery);
		return this;
	}
	
	public SQLCondition inSet(String where) {
		builder.append("IN (").append(where).append(") ");
		return this;
	}
	/***
	 * Condition second argument
	 * @param subquery			Subquery in which the target is
	 * @return					condition
	 */
	public SQLCondition inSubquery(SQLSubquery subquery) {
		builder.append("IN (").append(subquery.create()).append(") ");
		return this;
	}
	public SQLCondition notInSet(String where) {
		builder.append("NOT IN (").append(where).append(") ");
		return this;
	}
	/***
	 * Condition second argument
	 * @param subquery			Subquery in which the target is
	 * @return					condition
	 */
	public SQLCondition notInSubquery(SQLSubquery subquery) {
		builder.append("NOT IN (").append(subquery.create()).append(") ");
		return this;
	}

	public SQLCondition noEqualsTo(String attributeValue) { builder.append("<>\"").append(attributeValue).append("\" "); return this; }

	//-- Equals --//
	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition equalsTo(Object attributeValue) { builder.append("= \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition equalsTo(char attributeValue) { builder.append("= \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition equalsTo(int attributeValue) { builder.append("= \"").append(attributeValue).append("\" "); return this; }
	
	public SQLCondition equalsTo(Long attributeValue) { builder.append("= \"").append(attributeValue).append("\" "); return this; }

	
	//-- Larger than --//
	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition largerThan(String attributeValue) { builder.append("> \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition largerThan(char attributeValue) { builder.append("> \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition largerThan(int attributeValue) { builder.append("> \"").append(attributeValue).append("\" "); return this; }

	//-- Less than --//
	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition lessThan(String attributeValue) { builder.append("< \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition lessThan(char attributeValue) { builder.append("< \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition lessThan(int attributeValue) { builder.append("< \"").append(attributeValue).append("\" "); return this; }

	//-- Larger than or equal to --//
	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition largerThanOrEqualTo(String attributeValue) { builder.append(">= \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition largerThanOrEqualTo(char attributeValue) { builder.append(">= \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition largerThanOrEqualTo(int attributeValue) { builder.append(">= \"").append(attributeValue).append("\" "); return this; }

	//-- Less than or equal to --//
	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition lessThanOrEqualTo(String attributeValue) { builder.append("<= \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition lessThanOrEqualTo(char attributeValue) { builder.append("<= \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Condition second argument
	 * @param attributeValue	Second argument in condition 
	 * @return					condition
	 */
	public SQLCondition lessThanOrEqualTo(int attributeValue) { builder.append("<= \"").append(attributeValue).append("\" "); return this; }

	/***
	 * Reset condition
	 * @return				condition
	 */
	public SQLCondition clear() {
		builder = new StringBuilder().append(' ');
		return this;
	}

	/***
	 * Return the final condition
	 * @return condition
	 */
	public String create() {
		return toString();
	}

	/***
	 * Return the final condition
	 */
	@Override
	public String toString() {
		return builder.toString().trim();
	}
	public SQLCondition andWhereAttribute(Map<String, Object> paramMap)
	{
		if(IsKit.isNullOrEmpty(paramMap)) {
			return this;
		}
		for(String key: paramMap.keySet()){
			if(builder.length() == 0) {
				builder.append(key).append("= \"").append(paramMap.get(key)).append("\" ");
			}
			else {
				builder.append(" AND ")
				.append(key).append("= \"").append(paramMap.get(key)).append("\" ");
			}
		}
		return this;
	}
	public SQLCondition inSubquery(Set<String> setParams) {
       	builder.append("IN (").append(StringUtils.join(setParams.toArray(), ",")).append(") ");
		return this;
	}
	public SQLCondition inSubquery(String[] param) {
       	builder.append("IN (").append(param).append(") ");
		return this;
	}
	public SQLCondition inSubquery(String param) {
       	builder.append("IN (").append(param).append(") ");
		return this;
	}
}
