package com.brilliance.mda.runtime.mda.impl;

import com.brilliance.mda.runtime.mda.IResult;
import com.brilliance.mda.runtime.mda.OpType;

public class Argument<E> implements IResult {
	public String fieldName;
	public OpType opType;
	public E value;
	public Object attachField;

	public Argument() {

	}

	public Argument(String fieldName) {
		this.fieldName = fieldName;
	}

	public Argument(String fieldName, OpType opType, E value) {
		this.fieldName = fieldName;
		this.opType = opType;
		this.value = value;
	}

	public Argument(String fieldName, OpType opType) {
		this.fieldName = fieldName;
		this.opType = opType;
		this.value = null;
	}

	public Argument(String fieldName, E value) {
		this(fieldName, OpType.EQ, value);
	}

	public Argument(OpType opType, E value) {
		this(null, opType, value);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument or(Argument arg1, Argument arg2) {
		return new Argument(OpType.OR, new Argument[]{arg1, arg2});
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument and(Argument arg1, Argument arg2) {
		return new Argument(OpType.AND, new Argument[]{arg1, arg2});
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument not(Argument argument) {
		return new Argument(OpType.NOT, argument);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument in(String column, Object[] values) {
		return new Argument(column, OpType.IN, values);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument between(String column, Object value1, Object value2) {
		return new Argument(column, OpType.BETWEEN, new Object[]{value1, value2});
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument eq(String column, Object value) {
		return new Argument(column, value);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument gt(String column, Object value) {
		return new Argument(column, OpType.GT, value);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument ge(String column, Object value) {
		return new Argument(column, OpType.GE, value);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument lt(String column, Object value) {
		return new Argument(column, OpType.LT, value);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument le(String column, Object value) {
		return new Argument(column, OpType.LE, value);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument isNotNull(String column) {
		return new Argument(column, OpType.ISNOTNULL);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument isNull(String column) {
		return new Argument(column, OpType.ISNULL);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument like(String column, Object value) {
		return new Argument(column, OpType.LIKE, value);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public static Argument notLike(String column, Object value) {
		return new Argument(column, OpType.NOTLIKE, value);
	}

	@SuppressWarnings({"rawtypes"})
	public Argument and(Argument argument) {
		return this.opType == null ? argument : and(this, argument);
	}

	@SuppressWarnings({"rawtypes"})
	public Argument and(String fieldName, Object value) {
		return and(fieldName, OpType.EQ, value);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public Argument and(String fieldName, OpType opType) {
		return and(new Argument(fieldName, opType));
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public Argument and(String fieldName, OpType opType, Object value) {
		return and(new Argument(fieldName, opType, value));
	}

	@SuppressWarnings({"rawtypes"})
	public Argument or(Argument argument) {
		return this.opType == null ? argument : or(this, argument);
	}

	@SuppressWarnings({"rawtypes"})
	public Argument or(String fieldName, Object value) {
		return or(fieldName, OpType.EQ, value);
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public Argument or(String fieldName, OpType opType) {
		return or(new Argument(fieldName, opType));
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	public Argument or(String fieldName, OpType opType, Object value) {
		return or(new Argument(fieldName, opType, value));
	}


	@Override
	public Object setValue(Object value) {
		this.value = (E) value;
		return value;
	}

	@Override
	public E getValue() {
		return value;
	}

	@Override
	public Class getDataType() {
		return this.getClass();
	}

	public String getFieldName() {
		return this.fieldName;
	}

	@Override
	public String getName() {
		return this.fieldName;
	}

	@Override
	public int compareTo(Object o) {
		return 0;
	}

	public static <T> Argument<T> box(T value){
		return new Argument<T>("",value);
	}
}
