/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You 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 org.apache.poi.ss.formula;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.poi.hssf.record.formula.eval.BlankEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.usermodel.HSSFCell;

/**
 * Instances of this class keep track of multiple dependent cell evaluations due
 * to recursive calls to {@link WorkbookEvaluator#evaluate(HSSFCell)}
 * The main purpose of this class is to detect an attempt to evaluate a cell
 * that is already being evaluated. In other words, it detects circular
 * references in spreadsheet formulas.
 *
 * @author Josh Micich
 */
final class EvaluationTracker {
	// TODO - consider deleting this class and letting CellEvaluationFrame take care of itself
	private final List _evaluationFrames;
	private final Set _currentlyEvaluatingCells;
	private final EvaluationCache _cache;

	public EvaluationTracker(EvaluationCache cache) {
		_cache = cache;
		_evaluationFrames = new ArrayList();
		_currentlyEvaluatingCells = new HashSet();
	}

	/**
	 * Notifies this evaluation tracker that evaluation of the specified cell is
	 * about to start.<br/>
	 *
	 * In the case of a <code>true</code> return code, the caller should
	 * continue evaluation of the specified cell, and also be sure to call
	 * <tt>endEvaluate()</tt> when complete.<br/>
	 *
	 * In the case of a <code>null</code> return code, the caller should
	 * return an evaluation result of
	 * <tt>ErrorEval.CIRCULAR_REF_ERROR<tt>, and not call <tt>endEvaluate()</tt>.
	 * <br/>
	 * @return <code>false</code> if the specified cell is already being evaluated
	 */
	public boolean startEvaluate(FormulaCellCacheEntry cce) {
		if (cce == null) {
			throw new IllegalArgumentException("cellLoc must not be null");
		}
		if (_currentlyEvaluatingCells.contains(cce)) {
			return false;
		}
		_currentlyEvaluatingCells.add(cce);
		_evaluationFrames.add(new CellEvaluationFrame(cce));
		return true;
	}

	public void updateCacheResult(ValueEval result) {

		int nFrames = _evaluationFrames.size();
		if (nFrames < 1) {
			throw new IllegalStateException("Call to endEvaluate without matching call to startEvaluate");
		}
		CellEvaluationFrame frame = (CellEvaluationFrame) _evaluationFrames.get(nFrames-1);

		frame.updateFormulaResult(result);
	}

	/**
	 * Notifies this evaluation tracker that the evaluation of the specified cell is complete. <p/>
	 *
	 * Every successful call to <tt>startEvaluate</tt> must be followed by a call to <tt>endEvaluate</tt> (recommended in a finally block) to enable
	 * proper tracking of which cells are being evaluated at any point in time.<p/>
	 *
	 * Assuming a well behaved client, parameters to this method would not be
	 * required. However, they have been included to assert correct behaviour,
	 * and form more meaningful error messages.
	 */
	public void endEvaluate(CellCacheEntry cce) {

		int nFrames = _evaluationFrames.size();
		if (nFrames < 1) {
			throw new IllegalStateException("Call to endEvaluate without matching call to startEvaluate");
		}

		nFrames--;
		CellEvaluationFrame frame = (CellEvaluationFrame) _evaluationFrames.get(nFrames);
		if (cce != frame.getCCE()) {
			throw new IllegalStateException("Wrong cell specified. ");
		}
		// else - no problems so pop current frame
		_evaluationFrames.remove(nFrames);
		_currentlyEvaluatingCells.remove(cce);
	}

	public void acceptFormulaDependency(CellCacheEntry cce) {
		// Tell the currently evaluating cell frame that it has a dependency on the specified
		int prevFrameIndex = _evaluationFrames.size()-1;
		if (prevFrameIndex < 0) {
			// Top level frame, there is no 'cell' above this frame that is using the current cell
		} else {
			CellEvaluationFrame consumingFrame = (CellEvaluationFrame) _evaluationFrames.get(prevFrameIndex);
			consumingFrame.addSensitiveInputCell(cce);
		}
	}

	public void acceptPlainValueDependency(int bookIndex, int sheetIndex,
			int rowIndex, int columnIndex, ValueEval value) {
		// Tell the currently evaluating cell frame that it has a dependency on the specified
		int prevFrameIndex = _evaluationFrames.size() - 1;
		if (prevFrameIndex < 0) {
			// Top level frame, there is no 'cell' above this frame that is using the current cell
		} else {
			CellEvaluationFrame consumingFrame = (CellEvaluationFrame) _evaluationFrames.get(prevFrameIndex);
			if (value == BlankEval.INSTANCE) {
				consumingFrame.addUsedBlankCell(bookIndex, sheetIndex, rowIndex, columnIndex);
			} else {
				PlainValueCellCacheEntry cce = _cache.getPlainValueEntry(bookIndex, sheetIndex,
						rowIndex, columnIndex, value);
				consumingFrame.addSensitiveInputCell(cce);
			}
		}
	}
}
