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

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

import org.apache.poi.common.usermodel.GenericRecord;
import org.apache.poi.util.GenericRecordJsonWriter;
import org.apache.poi.util.GenericRecordUtil;
import org.apache.poi.util.LittleEndianOutput;

/**
 * EXTERNSHEET (0x0017)<p>
 * A List of Indexes to  EXTERNALBOOK (supplemental book) Records
 */
public class ExternSheetRecord extends StandardRecord {

    public static final short sid = 0x0017;
	private final List<RefSubRecord> _list = new ArrayList<>();

	private static final class RefSubRecord implements GenericRecord {
		public static final int ENCODED_SIZE = 6;

		/** index to External Book Block (which starts with a EXTERNALBOOK record) */
		private final int _extBookIndex;
		private int _firstSheetIndex; // may be -1 (0xFFFF)
		private int _lastSheetIndex;  // may be -1 (0xFFFF)

		public RefSubRecord(int extBookIndex, int firstSheetIndex, int lastSheetIndex) {
			_extBookIndex = extBookIndex;
			_firstSheetIndex = firstSheetIndex;
			_lastSheetIndex = lastSheetIndex;
		}

		public RefSubRecord(RefSubRecord other) {
			_extBookIndex = other._extBookIndex;
			_firstSheetIndex = other._firstSheetIndex;
			_lastSheetIndex = other._lastSheetIndex;
		}

		/**
		 * @param in the RecordInputstream to read the record from
		 */
		public RefSubRecord(RecordInputStream in) {
			this(in.readShort(), in.readShort(), in.readShort());
		}

		public int getExtBookIndex(){
			return _extBookIndex;
		}
		public int getFirstSheetIndex(){
			return _firstSheetIndex;
		}
		public int getLastSheetIndex(){
			return _lastSheetIndex;
		}

		@Override
		public String toString() {
			return GenericRecordJsonWriter.marshal(this);
		}

		public void serialize(LittleEndianOutput out) {
			out.writeShort(_extBookIndex);
			out.writeShort(_firstSheetIndex);
			out.writeShort(_lastSheetIndex);
		}

		@Override
		public Map<String, Supplier<?>> getGenericProperties() {
			return GenericRecordUtil.getGenericProperties(
				"extBookIndex", this::getExtBookIndex,
				"firstSheetIndex", this::getFirstSheetIndex,
				"lastSheetIndex", this::getLastSheetIndex
			);
		}
	}

	public ExternSheetRecord() {}

	public ExternSheetRecord(ExternSheetRecord other) {
		other._list.stream().map(RefSubRecord::new).forEach(_list::add);
	}

	public ExternSheetRecord(RecordInputStream in) {
		int nItems  = in.readShort();

		for (int i = 0 ; i < nItems ; ++i) {
			RefSubRecord rec = new RefSubRecord(in);
			_list.add(rec);
		}
	}


	/**
	 * @return number of REF structures
	 */
	public int getNumOfRefs() {
		return _list.size();
	}

	/**
	 * adds REF struct (ExternSheetSubRecord)
	 * @param rec REF struct
	 */
	public void addREFRecord(RefSubRecord rec) {
		_list.add(rec);
	}

	/** returns the number of REF Records, which is in model
	 * @return number of REF records
	 */
	public int getNumOfREFRecords() {
		return _list.size();
	}

	@Override
	protected int getDataSize() {
		return 2 + _list.size() * RefSubRecord.ENCODED_SIZE;
	}

	@Override
	public void serialize(LittleEndianOutput out) {
		int nItems = _list.size();

		out.writeShort(nItems);

		for (int i = 0; i < nItems; i++) {
			getRef(i).serialize(out);
		}
	}

	private RefSubRecord getRef(int i) {
		return _list.get(i);
	}

	public void removeSheet(int sheetIdx) {
        int nItems = _list.size();
        for (int i = 0; i < nItems; i++) {
            RefSubRecord refSubRecord = _list.get(i);
            if(refSubRecord.getFirstSheetIndex() == sheetIdx &&
                    refSubRecord.getLastSheetIndex() == sheetIdx) {
            	// removing the entry would mess up the sheet index in Formula of NameRecord
            	_list.set(i, new RefSubRecord(refSubRecord.getExtBookIndex(), -1, -1));
            } else if (refSubRecord.getFirstSheetIndex() > sheetIdx &&
                    refSubRecord.getLastSheetIndex() > sheetIdx) {
                _list.set(i, new RefSubRecord(refSubRecord.getExtBookIndex(), refSubRecord.getFirstSheetIndex()-1, refSubRecord.getLastSheetIndex()-1));
            }
        }
	}

	/**
	 * return the non static version of the id for this record.
	 */
	@Override
	public short getSid() {
		return sid;
	}

    /**
     * @param refIndex specifies the n-th refIndex
     *
     * @return the index of the SupBookRecord for this index
     */
    public int getExtbookIndexFromRefIndex(int refIndex) {
        RefSubRecord refRec = getRef(refIndex);
        return refRec.getExtBookIndex();
    }

	/**
	 * @param extBookIndex external sheet reference index
	 *
	 * @return -1 if not found
	 */
	public int findRefIndexFromExtBookIndex(int extBookIndex) {
		int nItems = _list.size();
		for (int i = 0; i < nItems; i++) {
			if (getRef(i).getExtBookIndex() == extBookIndex) {
				return i;
			}
		}
		return -1;
	}

    /**
     * Returns the first sheet that the reference applies to, or
     *  -1 if the referenced sheet can't be found, or -2 if the
     *  reference is workbook scoped.
     *
     * @param extRefIndex external sheet reference index
     *
     * @return the first sheet that the reference applies to, or
     *  -1 if the referenced sheet can't be found, or -2 if the
     *  reference is workbook scoped
     */
	public int getFirstSheetIndexFromRefIndex(int extRefIndex) {
		return getRef(extRefIndex).getFirstSheetIndex();
	}

    /**
     * Returns the last sheet that the reference applies to, or
     *  -1 if the referenced sheet can't be found, or -2 if the
     *  reference is workbook scoped.
     * For a single sheet reference, the first and last should be
     *  the same.
     *
     * @param extRefIndex external sheet reference index
     *
     * @return the last sheet that the reference applies to, or
     *  -1 if the referenced sheet can't be found, or -2 if the
     *  reference is workbook scoped.
     */
    public int getLastSheetIndexFromRefIndex(int extRefIndex) {
        return getRef(extRefIndex).getLastSheetIndex();
    }

	/**
     * Add a zero-based reference to a {@link org.apache.poi.hssf.record.SupBookRecord}.
     * <p>
     *  If the type of the SupBook record is same-sheet referencing, Add-In referencing,
     *  DDE data source referencing, or OLE data source referencing,
     *  then no scope is specified and this value <em>MUST</em> be -2. Otherwise,
     *  the scope must be set as follows:
     *  <ol>
     *    <li><code>-2</code> Workbook-level reference that applies to the entire workbook.</li>
     *    <li><code>-1</code> Sheet-level reference. </li>
     *    <li><code>&gt;=0</code> Sheet-level reference. This specifies the first sheet in the reference.
     *    <p>If the SupBook type is unused or external workbook referencing,
     *    then this value specifies the zero-based index of an external sheet name,
     *    see {@link org.apache.poi.hssf.record.SupBookRecord#getSheetNames()}.
     *    This referenced string specifies the name of the first sheet within the external workbook that is in scope.
     *    This sheet MUST be a worksheet or macro sheet.</p>
     *
     *    <p>If the supporting link type is self-referencing, then this value specifies the zero-based index of a
     *    {@link org.apache.poi.hssf.record.BoundSheetRecord} record in the workbook stream that specifies
     *    the first sheet within the scope of this reference. This sheet MUST be a worksheet or a macro sheet.
     *    </p>
     *    </li>
     *  </ol>
     *
     * @param extBookIndex  the external book block index
     * @param firstSheetIndex  the scope, must be -2 for add-in references
     * @param lastSheetIndex   the scope, must be -2 for add-in references
	 * @return index of newly added ref
	 */
	public int addRef(int extBookIndex, int firstSheetIndex, int lastSheetIndex) {
		_list.add(new RefSubRecord(extBookIndex, firstSheetIndex, lastSheetIndex));
		return _list.size() - 1;
	}

	public int getRefIxForSheet(int externalBookIndex, int firstSheetIndex, int lastSheetIndex) {
		int nItems = _list.size();
		for (int i = 0; i < nItems; i++) {
			RefSubRecord ref = getRef(i);
			if (ref.getExtBookIndex() != externalBookIndex) {
				continue;
			}
			if (ref.getFirstSheetIndex() == firstSheetIndex &&
			        ref.getLastSheetIndex() == lastSheetIndex) {
				return i;
			}
		}
		return -1;
	}

	public static ExternSheetRecord combine(ExternSheetRecord[] esrs) {
		ExternSheetRecord result = new ExternSheetRecord();
		for (ExternSheetRecord esr : esrs) {
			int nRefs = esr.getNumOfREFRecords();
			for (int j=0; j<nRefs; j++) {
				result.addREFRecord(esr.getRef(j));
			}
		}
		return result;
	}

	@Override
	public ExternSheetRecord copy() {
		return new ExternSheetRecord(this);
	}

	@Override
	public HSSFRecordTypes getGenericRecordType() {
		return HSSFRecordTypes.EXTERN_SHEET;
	}

	@Override
	public Map<String, Supplier<?>> getGenericProperties() {
		return GenericRecordUtil.getGenericProperties("refrec", () -> _list);
	}
}
