/* ====================================================================
   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.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

import org.apache.poi.ss.util.WorkbookUtil;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.GenericRecordUtil;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.StringUtil;

/**
 * Defines a sheet within a workbook. Basically stores the sheet name and
 * tells where the Beginning of file record is within the HSSF file.
 */
public final class BoundSheetRecord extends StandardRecord {
	public static final short sid = 0x0085;
	private static final BitField hiddenFlag = BitFieldFactory.getInstance(0x01);
	private static final BitField veryHiddenFlag = BitFieldFactory.getInstance(0x02);

	private int field_1_position_of_BOF;
	private int field_2_option_flags;
	private int field_4_isMultibyteUnicode;
	private String field_5_sheetname;

	public BoundSheetRecord(String sheetname) {
		field_2_option_flags = 0;
		setSheetname(sheetname);
	}

	public BoundSheetRecord(BoundSheetRecord other) {
		super(other);
		field_1_position_of_BOF = other.field_1_position_of_BOF;
		field_2_option_flags = other.field_2_option_flags;
		field_4_isMultibyteUnicode = other.field_4_isMultibyteUnicode;
		field_5_sheetname = other.field_5_sheetname;
	}

	/**
	 * UTF8: sid + len + bof + flags + len(str) + unicode + str 2 + 2 + 4 + 2 +
	 * 1 + 1 + len(str)
	 *
	 * UNICODE: sid + len + bof + flags + len(str) + unicode + str 2 + 2 + 4 + 2 +
	 * 1 + 1 + 2 * len(str)
	 *
	 * @param in the record stream to read from
	 */
	public BoundSheetRecord(RecordInputStream in) {
        byte[] buf = new byte[LittleEndianConsts.INT_SIZE];
	    in.readPlain(buf, 0, buf.length);
		field_1_position_of_BOF = LittleEndian.getInt(buf);
		field_2_option_flags = in.readUShort();
		int field_3_sheetname_length = in.readUByte();
		field_4_isMultibyteUnicode = in.readByte();

		if (isMultibyte()) {
			field_5_sheetname = in.readUnicodeLEString(field_3_sheetname_length);
		} else {
			field_5_sheetname = in.readCompressedUnicode(field_3_sheetname_length);
		}
	}

	/**
	 * set the offset in bytes of the Beginning of File Marker within the HSSF
	 * Stream part of the POIFS file
	 *
	 * @param pos offset in bytes
	 */
	public void setPositionOfBof(int pos) {
		field_1_position_of_BOF = pos;
	}

	/**
	 * Set the sheetname for this sheet.  (this appears in the tabs at the bottom)
	 * @param sheetName the name of the sheet
	 * @see org.apache.poi.ss.util.WorkbookUtil#createSafeSheetName(String nameProposal)
	 *      for a safe way to create valid names
	 * @throws IllegalArgumentException if sheet name will cause excel to crash.
	 */
	public void setSheetname(String sheetName) {

		WorkbookUtil.validateSheetName(sheetName);
		field_5_sheetname = sheetName;
		field_4_isMultibyteUnicode = StringUtil.hasMultibyte(sheetName) ?  1 : 0;
	}

	/**
	 * get the offset in bytes of the Beginning of File Marker within the HSSF Stream part of the POIFS file
	 *
	 * @return offset in bytes
	 */
	public int getPositionOfBof() {
		return field_1_position_of_BOF;
	}

	private boolean isMultibyte() {
		return (field_4_isMultibyteUnicode & 0x01) != 0;
	}

	/**
	 * get the sheetname for this sheet.  (this appears in the tabs at the bottom)
	 * @return sheetname the name of the sheet
	 */
	public String getSheetname() {
		return field_5_sheetname;
	}

	protected int getDataSize() {
		return 8 + field_5_sheetname.length() * (isMultibyte() ? 2 : 1);
	}

	public void serialize(LittleEndianOutput out) {
		out.writeInt(getPositionOfBof());
		out.writeShort(field_2_option_flags);

		String name = field_5_sheetname;
		out.writeByte(name.length());
		out.writeByte(field_4_isMultibyteUnicode);

		if (isMultibyte()) {
			StringUtil.putUnicodeLE(name, out);
		} else {
			StringUtil.putCompressedUnicode(name, out);
		}
	}

	public short getSid() {
		return sid;
	}

	/**
	 * Is the sheet hidden? Different from very hidden
	 *
	 * @return {@code true} if hidden
	 */
	public boolean isHidden() {
		return hiddenFlag.isSet(field_2_option_flags);
	}

	/**
	 * Is the sheet hidden? Different from very hidden
	 *
	 * @param hidden {@code true} if hidden
	 */
	public void setHidden(boolean hidden) {
		field_2_option_flags = hiddenFlag.setBoolean(field_2_option_flags, hidden);
	}

	/**
	 * Is the sheet very hidden? Different from (normal) hidden
	 *
	 * @return {@code true} if very hidden
	 */
	public boolean isVeryHidden() {
		return veryHiddenFlag.isSet(field_2_option_flags);
	}

	/**
	 * Is the sheet very hidden? Different from (normal) hidden
	 *
	 * @param veryHidden {@code true} if very hidden
	 */
	public void setVeryHidden(boolean veryHidden) {
		field_2_option_flags = veryHiddenFlag.setBoolean(field_2_option_flags, veryHidden);
	}

	/**
	 * Converts a List of {@link BoundSheetRecord}s to an array and sorts by the position of their
	 * BOFs.
	 *
	 * @param boundSheetRecords the boundSheetRecord list to arrayify
	 *
	 * @return the sorted boundSheetRecords
	 */
	public static BoundSheetRecord[] orderByBofPosition(List<BoundSheetRecord> boundSheetRecords) {
		BoundSheetRecord[] bsrs = new BoundSheetRecord[boundSheetRecords.size()];
		boundSheetRecords.toArray(bsrs);
		Arrays.sort(bsrs, BoundSheetRecord::compareRecords);
	 	return bsrs;
	}

	private static int compareRecords(BoundSheetRecord bsr1, BoundSheetRecord bsr2) {
		return bsr1.getPositionOfBof() - bsr2.getPositionOfBof();
	}

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

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

	@Override
	public Map<String, Supplier<?>> getGenericProperties() {
		return GenericRecordUtil.getGenericProperties(
			"bof", this::getPositionOfBof,
			"optionFlags", () -> field_2_option_flags,
			"multiByte", this::isMultibyte,
			"sheetName", this::getSheetname,
			"hidden", this::isHidden,
			"veryHidden", this::isVeryHidden
		);
	}
}
