/* ************************************************************************
#
#  DivConq
#
#  http://divconq.com/
#
#  Copyright:
#    Copyright 2012 eTimeline, LLC. All rights reserved.
#
#  License:
#    See the license.txt file in the project's top-level directory for details.
#
#  Authors:
#    * Andy White
#
************************************************************************ */
package divconq.db.query;

import org.joda.time.DateTime;

import divconq.db.QueryRequest;
import divconq.lang.BigDateTime;
import divconq.lang.OperationResult;
import divconq.struct.RecordStruct;
import divconq.struct.Struct;
import divconq.util.StringUtil;

/**
 * Request that a single database record be loaded.
 * 
 * @author Andy
 *
 */
public class LoadRecordRequest extends QueryRequest {
	protected SelectFields select = null;
	
	public void setCompact(boolean v) {
		((RecordStruct)this.parameters).setField("Compact", v);
	}
	
	public void setHistorical(boolean v) {
		((RecordStruct)this.parameters).setField("Historical", v);
	}
	
	/**
	 * @param table name
	 * @param id of record
	 */
	public LoadRecordRequest(String table, String id) {
		this(table, id, new BigDateTime(new DateTime()), null, null, null);
	}
	
	/**
	 * @param table name
	 * @param id of record
	 * @param when date for which data (Dynamic fields) should be loaded
	 */
	public LoadRecordRequest(String table, String id, BigDateTime when) {
		this(table, id, when, null, null, null);
	}
	
	/**
	 * @param table name
	 * @param id of record
	 * @param when date for which data (Dynamic fields) should be loaded
	 */
	public LoadRecordRequest(String table, String id, DateTime when) {
		this(table, id, (when != null) ? new BigDateTime(when) : null, null, null, null);
	}
	
	/**
	 * @param table name
	 * @param id of record
	 * @param select fields/subqueries to return
	 */
	public LoadRecordRequest(String table, String id, SelectFields select) {
		this(table, id, new BigDateTime(new DateTime()), select, null, null);
	}
	
	/**
	 * @param table name
	 * @param id of record
	 * @param when date for which data (Dynamic fields) should be loaded
	 * @param select fields/subqueries to return
	 */
	public LoadRecordRequest(String table, String id, BigDateTime when, SelectFields select) {
		this(table, id, when, select, null, null);
	}
	
	/**
	 * @param table name
	 * @param id of record
	 * @param when date for which data (Dynamic fields) should be loaded
	 * @param select fields/subqueries to return
	 */
	public LoadRecordRequest(String table, String id, DateTime when, SelectFields select) {
		this(table, id, (when != null) ? new BigDateTime(when) : null, select, null, null);
	}
	
	/**
	 * @param table name
	 * @param id of record
	 * @param when date for which data (Dynamic fields) should be loaded
	 * @param select fields/subqueries to return
	 * @param filter name of filter procedure (check if access to record is allowed)
	 */
	public LoadRecordRequest(String table, String id, BigDateTime when, SelectFields select, String filter) {
		this(table, id, when, select, filter, null);
	}
	
	/**
	 * @param table name
	 * @param id of record
	 * @param when date for which data (Dynamic fields) should be loaded
	 * @param select fields/subqueries to return
	 * @param filter name of filter procedure (check if access to record is allowed)
	 */
	public LoadRecordRequest(String table, String id, DateTime when, SelectFields select, String filter) {
		this(table, id, (when != null) ? new BigDateTime(when) : null, select, filter, null);
	}
	
	/**
	 * @param table name
	 * @param id of record
	 * @param when date for which data (Dynamic fields) should be loaded
	 * @param select fields/subqueries to return
	 * @param filter name of filter procedure (check if access to record is allowed)
	 * @param extra additional parameters (for filter)
	 */
	public LoadRecordRequest(String table, String id, DateTime when, SelectFields select, String filter, Struct extra) {
		this(table, id, (when != null) ? new BigDateTime(when) : null, select, filter, extra);
	}
	
	/**
	 * @param table name
	 * @param id of record
	 * @param when date for which data (Dynamic fields) should be loaded
	 * @param select fields/subqueries to return
	 * @param filter name of filter procedure (check if access to record is allowed)
	 * @param extra additional parameters (for filter)
	 */
	public LoadRecordRequest(String table, String id, BigDateTime when, SelectFields select, String filter, Struct extra) {
		super("dcLoadRecord");
		
		RecordStruct params = new RecordStruct();
		
		this.parameters = params;
	
		params.setField("Table", table);
		params.setField("Id", id);		
		
		if (StringUtil.isNotEmpty(filter))
			params.setField("Filter", filter);
		
		if (when != null)
			params.setField("When", when);
		
		if (extra != null)
			params.setField("Extra", extra);
		
		if (select != null)
			params.setField("Select", select.getFields());
		
		this.select = select;		
	}
	
	@Override
	public void validate(OperationResult or) {
		super.validate(or);
		
		// TODO validate the select and order tree, prove that all fields/tables are real
	}
}
