/*******************************************************************************
 * Copyright 2017 Bstek
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.  You may obtain a copy
 * of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations under
 * the License.
 ******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.table;

import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.action.AbstractAction;
import com.itheima.sfbx.framework.rule.action.Action;
import com.itheima.sfbx.framework.rule.action.ConsolePrintAction;
import com.itheima.sfbx.framework.rule.action.VariableAssignAction;
import com.itheima.sfbx.framework.rule.model.rule.Rhs;
import com.itheima.sfbx.framework.rule.model.rule.Rule;
import com.itheima.sfbx.framework.rule.model.rule.Value;
import com.itheima.sfbx.framework.rule.model.rule.lhs.And;
import com.itheima.sfbx.framework.rule.model.rule.lhs.Criterion;
import com.itheima.sfbx.framework.rule.model.rule.lhs.Lhs;
import com.itheima.sfbx.framework.rule.model.table.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Jacky.gao
 * @since 2015年1月20日
 */
public class DecisionTableRulesBuilder {
	private CellContentBuilder cellContentBuilder;
	public List<Rule> buildRules(DecisionTable table){
		List<Rule> rules=new ArrayList<Rule>();
		List<Row> rows=table.getRows();
		List<Column> columns=table.getColumns();
		for(Row row:rows){
			Rule rule=new Rule();
			rule.setDebug(table.getDebug());
			rule.setSalience(table.getSalience());
			rule.setExpiresDate(table.getExpiresDate());
			rule.setEffectiveDate(table.getEffectiveDate());
			rule.setEnabled(table.getEnabled());
			rule.setName("r"+row.getNum());
			Lhs lhs=new Lhs();
			And and=new And();
			lhs.setCriterion(and);
			rule.setLhs(lhs);
			Rhs rhs=new Rhs();
			rule.setRhs(rhs);
			rules.add(rule);
			Value value=null;
			for(Column col:columns){
				Cell cell=getCell(table,row.getNum(),col.getNum());
				ColumnType type=col.getType();
				switch(type){
				case Criteria:
					Criterion criterion=cellContentBuilder.buildCriterion(cell,col);
					if(criterion!=null){
						and.addCriterion(criterion);						
					}
					break;
				case ConsolePrint:
					value=cell.getValue();
					if(value!=null){
						ConsolePrintAction consolePrintAction=new ConsolePrintAction();
						consolePrintAction.setPriority(1000-col.getNum());
						consolePrintAction.setValue(value);
						rhs.addAction(consolePrintAction);
					}
					break;
				case Assignment:
					value=cell.getValue();
					if(value!=null){
						VariableAssignAction variableAssignAction=new VariableAssignAction();
						variableAssignAction.setPriority(1000-col.getNum());
						variableAssignAction.setValue(value);
						variableAssignAction.setDatatype(col.getDatatype());
						variableAssignAction.setVariableName(col.getVariableName());
						variableAssignAction.setVariableLabel(col.getVariableLabel());
						variableAssignAction.setVariableCategory(col.getVariableCategory());
						rhs.addAction(variableAssignAction);
					}
					break;
				case ExecuteMethod:
					Action action=cell.getAction();
					if(action!=null){
						AbstractAction aa=(AbstractAction)action;
						aa.setPriority(1000-col.getNum());
						rhs.addAction(aa);
					}
					break;
				}
			}
		}
		return rules;
	}
	private Cell getCell(DecisionTable table,int row,int column){
		Map<String,Cell> cellMap=table.getCellMap();
		Cell cell=null;
		for(int i=row;i>-1;i--){
			String key=table.buildCellKey(i,column);
			if(cellMap.containsKey(key)){
				cell=cellMap.get(key);
				break;
			}
		}
		if(cell==null){
			throw new RuleException("Decision table cell["+row+","+column+"] not exist.");
		}
		return cell;
	}
	public void setCellContentBuilder(CellContentBuilder cellContentBuilder) {
		this.cellContentBuilder = cellContentBuilder;
	}
}
