/* ====================================================================
   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.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.apache.poi.common.Duplicatable;
import org.apache.poi.common.usermodel.GenericRecord;
import org.apache.poi.util.GenericRecordJsonWriter;
import org.apache.poi.util.GenericRecordUtil;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.LittleEndianOutputStream;

/**
 * Subrecords are part of the OBJ class.
 */
public abstract class SubRecord implements Duplicatable, GenericRecord {

	public enum SubRecordTypes {
		UNKNOWN(-1, UnknownSubRecord::new),
		END(0x0000, EndSubRecord::new),
		GROUP_MARKER(0x0006, GroupMarkerSubRecord::new),
		FT_CF(0x0007, FtCfSubRecord::new),
		FT_PIO_GRBIT(0x0008, FtPioGrbitSubRecord::new),
		EMBEDDED_OBJECT_REF(0x0009, EmbeddedObjectRefSubRecord::new),
		FT_CBLS(0x000C, FtCblsSubRecord::new),
		NOTE_STRUCTURE(0x000D, NoteStructureSubRecord::new),
		LBS_DATA(0x0013, LbsDataSubRecord::new),
		COMMON_OBJECT_DATA(0x0015, CommonObjectDataSubRecord::new),
		;

		@FunctionalInterface
		public interface RecordConstructor<T extends SubRecord> {
			/**
			 * read a sub-record from the supplied stream
			 *
			 * @param in    the stream to read from
			 * @param cmoOt the objectType field of the containing CommonObjectDataSubRecord,
			 *   we need it to propagate to next sub-records as it defines what data follows
			 * @return the created sub-record
			 */
			T apply(LittleEndianInput in, int size, int cmoOt);
		}

		private static final Map<Short,SubRecordTypes> LOOKUP =
			Arrays.stream(values()).collect(Collectors.toMap(SubRecordTypes::getSid, Function.identity()));

		public final short sid;
		public final RecordConstructor<?> recordConstructor;

		SubRecordTypes(int sid, RecordConstructor<?> recordConstructor) {
			this.sid = (short)sid;
			this.recordConstructor = recordConstructor;
		}

		public static SubRecordTypes forSID(int sid) {
			return LOOKUP.getOrDefault((short)sid, UNKNOWN);
		}

		public short getSid() {
			return sid;
		}
	}


	//arbitrarily selected; may need to increase
	private static final int MAX_RECORD_LENGTH = 1_000_000;

	protected SubRecord() {}

	protected SubRecord(SubRecord other) {}

	/**
     * read a sub-record from the supplied stream
     *
     * @param in    the stream to read from
     * @param cmoOt the objectType field of the containing CommonObjectDataSubRecord,
     *   we need it to propagate to next sub-records as it defines what data follows
     * @return the created sub-record
     */
    public static SubRecord createSubRecord(LittleEndianInput in, int cmoOt) {
		int sid = in.readUShort();
		// Often (but not always) the datasize for the sub-record
		int size = in.readUShort();
		SubRecordTypes srt = SubRecordTypes.forSID(sid);
		return srt.recordConstructor.apply(in, size, srt == SubRecordTypes.UNKNOWN ? sid : cmoOt);
	}

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

	/**
	 * @return the size of the data for this record (which is always 4 bytes less than the total
	 * record size).  Note however, that ushort encoded after the record sid is usually but not
	 * always the data size.
	 */
	protected abstract int getDataSize();
	public byte[] serialize() {
		int size = getDataSize() + 4;
		ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
		serialize(new LittleEndianOutputStream(baos));
		if (baos.size() != size) {
			throw new RuntimeException("write size mismatch");
		}
		return baos.toByteArray();
	}

	public abstract void serialize(LittleEndianOutput out);


    /**
     * Whether this record terminates the sub-record stream.
     * There are two cases when this method must be overridden and return <code>true</code>
     *  - EndSubRecord (sid = 0x00)
     *  - LbsDataSubRecord (sid = 0x12)
     *
     * @return whether this record is the last in the sub-record stream
     */
    public boolean isTerminating(){
        return false;
    }

    private static final class UnknownSubRecord extends SubRecord {

		private final int _sid;
		private final byte[] _data;

		public UnknownSubRecord(LittleEndianInput in, int size, int sid) {
			_sid = sid;
	    	byte[] buf = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
	    	in.readFully(buf);
	        _data = buf;
		}
		@Override
		protected int getDataSize() {
			return _data.length;
		}
		@Override
		public void serialize(LittleEndianOutput out) {
			out.writeShort(_sid);
			out.writeShort(_data.length);
			out.write(_data);
		}

		@Override
		public UnknownSubRecord copy() {
			return this;
		}

		@Override
		public SubRecordTypes getGenericRecordType() {
			return SubRecordTypes.UNKNOWN;
		}

		@Override
		public Map<String, Supplier<?>> getGenericProperties() {
			return GenericRecordUtil.getGenericProperties(
				"sid", () -> _sid,
				"data", () -> _data
			);
		}
	}

	@Override
	public abstract SubRecord copy();

	@Override
	public abstract SubRecordTypes getGenericRecordType();
}
