/* ====================================================================
   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.Arrays;

import org.apache.poi.ss.formula.ptg.ExpPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.ptg.TblPtg;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianByteArrayInputStream;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;

/**
 * Encapsulates an encoded formula token array.
 *
 * @author Josh Micich
 */
public class Formula {

	private static final Formula EMPTY = new Formula(new byte[0], 0);

	/** immutable */
	private final byte[] _byteEncoding;
	private final int _encodedTokenLen;

	private Formula(byte[] byteEncoding, int encodedTokenLen) {
		_byteEncoding = byteEncoding.clone();
		_encodedTokenLen = encodedTokenLen;
//		if (false) { // set to true to eagerly check Ptg decoding
//			LittleEndianByteArrayInputStream in = new LittleEndianByteArrayInputStream(byteEncoding);
//			Ptg.readTokens(encodedTokenLen, in);
//			int nUnusedBytes = _byteEncoding.length - in.getReadIndex();
//			if (nUnusedBytes > 0) {
//				// TODO - this seems to occur when IntersectionPtg is present
//				// This example file "IntersectionPtg.xls"
//				// used by test: TestIntersectionPtg.testReading()
//				// has 10 bytes unused at the end of the formula
//				// 10 extra bytes are just 0x01 and 0x00
//				System.out.println(nUnusedBytes + " unused bytes at end of formula");
//			}
//		}
	}
	/**
	 * Convenience method for {@link #read(int, LittleEndianInput, int)}
	 */
	public static Formula read(int encodedTokenLen, LittleEndianInput in) {
		return read(encodedTokenLen, in, encodedTokenLen);
	}
	/**
	 * When there are no array constants present, <tt>encodedTokenLen</tt>==<tt>totalEncodedLen</tt>
	 * @param encodedTokenLen number of bytes in the stream taken by the plain formula tokens
	 * @param totalEncodedLen the total number of bytes in the formula (includes trailing encoding
	 * for array constants, but does not include 2 bytes for initial <tt>ushort encodedTokenLen</tt> field.
	 * @return A new formula object as read from the stream.  Possibly empty, never <code>null</code>.
	 */
	public static Formula read(int encodedTokenLen, LittleEndianInput in, int totalEncodedLen) {
		byte[] byteEncoding = new byte[totalEncodedLen];
		in.readFully(byteEncoding);
		return new Formula(byteEncoding, encodedTokenLen);
	}

	public Ptg[] getTokens() {
		LittleEndianInput in = new LittleEndianByteArrayInputStream(_byteEncoding);
		return Ptg.readTokens(_encodedTokenLen, in);
	}
	/**
	 * Writes  The formula encoding is includes:
	 * <ul>
	 * <li>ushort tokenDataLen</li>
	 * <li>tokenData</li>
	 * <li>arrayConstantData (if present)</li>
	 * </ul>
	 */
	public void serialize(LittleEndianOutput out) {
		out.writeShort(_encodedTokenLen);
		out.write(_byteEncoding);
	}

	public void serializeTokens(LittleEndianOutput out) {
		out.write(_byteEncoding, 0, _encodedTokenLen);
	}
	public void serializeArrayConstantData(LittleEndianOutput out) {
		int len = _byteEncoding.length-_encodedTokenLen;
		out.write(_byteEncoding, _encodedTokenLen, len);
	}


	/**
	 * @return total formula encoding length.  The formula encoding includes:
	 * <ul>
	 * <li>ushort tokenDataLen</li>
	 * <li>tokenData</li>
	 * <li>arrayConstantData (optional)</li>
	 * </ul>
	 * Note - this value is different to <tt>tokenDataLength</tt>
	 */
	public int getEncodedSize() {
		return 2 + _byteEncoding.length;
	}
	/**
	 * This method is often used when the formula length does not appear immediately before
	 * the encoded token data.
	 *
	 * @return the encoded length of the plain formula tokens.  This does <em>not</em> include
	 * the leading ushort field, nor any trailing array constant data.
	 */
	public int getEncodedTokenSize() {
		return _encodedTokenLen;
	}

	/**
	 * Creates a {@link Formula} object from a supplied {@link Ptg} array.
	 * Handles <code>null</code>s OK.
	 * @param ptgs may be <code>null</code>
	 * @return Never <code>null</code> (Possibly empty if the supplied <tt>ptgs</tt> is <code>null</code>)
	 */
	public static Formula create(Ptg[] ptgs) {
		if (ptgs == null || ptgs.length < 1) {
			return EMPTY;
		}
		int totalSize = Ptg.getEncodedSize(ptgs);
		byte[] encodedData = new byte[totalSize];
		Ptg.serializePtgs(ptgs, encodedData, 0);
		int encodedTokenLen = Ptg.getEncodedSizeWithoutArrayData(ptgs);
		return new Formula(encodedData, encodedTokenLen);
	}
	/**
	 * Gets the {@link Ptg} array from the supplied {@link Formula}.
	 * Handles <code>null</code>s OK.
	 *
	 * @param formula may be <code>null</code>
	 * @return possibly <code>null</code> (if the supplied <tt>formula</tt> is <code>null</code>)
	 */
	public static Ptg[] getTokens(Formula formula) {
		if (formula == null) {
			return null;
		}
		return formula.getTokens();
	}

	public Formula copy() {
		// OK to return this because immutable
		return this;
	}

	/**
	 * Gets the locator for the corresponding {@link org.apache.poi.hssf.record.SharedFormulaRecord},
     * {@link org.apache.poi.hssf.record.ArrayRecord} or {@link org.apache.poi.hssf.record.TableRecord}
     * if this formula belongs to such a grouping.  The {@link CellReference}
	 * returned by this method will  match the top left corner of the range of that grouping.
	 * The return value is usually not the same as the location of the cell containing this formula.
	 *
	 * @return the firstRow & firstColumn of an array formula or shared formula that this formula
	 * belongs to.  <code>null</code> if this formula is not part of an array or shared formula.
	 */
	public CellReference getExpReference() {
		byte[] data = _byteEncoding;
		if (data.length != 5) {
			// tExp and tTbl are always 5 bytes long, and the only ptg in the formula
			return null;
		}
		switch (data[0]) {
			case ExpPtg.sid:
				break;
			case TblPtg.sid:
				break;
			default:
				return null;
		}
		int firstRow = LittleEndian.getUShort(data, 1);
		int firstColumn = LittleEndian.getUShort(data, 3);
		return new CellReference(firstRow, firstColumn);
	}
	public boolean isSame(Formula other) {
		return Arrays.equals(_byteEncoding, other._byteEncoding);
	}
}
