/* ====================================================================
   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 static org.apache.poi.hssf.record.TestcaseRecordInputStream.confirmRecordEncoding;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

import org.apache.poi.util.HexRead;
import org.junit.jupiter.api.Test;

/**
 * Tests the serialization and deserialization of the TestEmbeddedObjectRefSubRecord
 * class works correctly.  Test data taken directly from a real Excel file.
 */
final class TestEmbeddedObjectRefSubRecord {

	private static final short EORSR_SID = EmbeddedObjectRefSubRecord.sid;

	@Test
	void testStore() {
		String data1
				= "20 00 05 00 FC 10 76 01 02 24 14 DF 00 03 10 00 "
				+ "00 46 6F 72 6D 73 2E 43 68 65 63 6B 42 6F 78 2E "
				+ "31 00 00 00 00 00 70 00 00 00 00 00 00 00 00 00 "
				+ "00 00";

		byte[] src = hr(data1);

		RecordInputStream in = TestcaseRecordInputStream.create(EORSR_SID, src);

		EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord(in, src.length);

		byte[] ser = record1.serialize();

		RecordInputStream in2 = TestcaseRecordInputStream.create(ser);
		EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2, ser.length-4);
		confirmRecordEncoding(EmbeddedObjectRefSubRecord.sid, src, ser);
		assertEquals(record1.getOLEClassName(), record2.getOLEClassName());

		byte[] ser2 = record1.serialize();
		assertArrayEquals(ser, ser2);
	}

	@Test
	void testCreate() {
		EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord();

		byte[] ser = record1.serialize();
		RecordInputStream in2 = TestcaseRecordInputStream.create(ser);
		EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2, ser.length-4);

		assertEquals(record1.getOLEClassName(), record2.getOLEClassName());
		assertEquals(record1.getStreamId(), record2.getStreamId());

		byte[] ser2 = record1.serialize();
		assertArrayEquals(ser, ser2);
	}

	@SuppressWarnings("squid:S2699")
	@Test
	void testCameraTool_bug45912() {
		/*
		 * taken from ftPictFmla sub-record in attachment 22645 (offset 0x40AB).
		 */
		byte[] data45912 = hr(
				"12 00 0B 00 F8 02 88 04 3B 00 " +
				"00 00 00 01 00 00 00 01 " +
				"00 00");
		RecordInputStream in = TestcaseRecordInputStream.create(EORSR_SID, data45912);

		EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in, data45912.length);
		byte[] ser2 = rec.serialize();
		confirmRecordEncoding(EmbeddedObjectRefSubRecord.sid, data45912, ser2);
	}

	private static byte[] hr(String string) {
		return HexRead.readFromString(string);
	}

	/**
	 * tests various examples of OLE controls
	 */
	@SuppressWarnings("squid:S2699")
	@Test
	void testVarious() {
		String[] rawData = {
			"12 00 0B 00 70 95 0B 05 3B 01 00 36 00 40 00 18 00 19 00 18",
			"12 00 0B 00 B0 4D 3E 03 3B 00 00 00 00 01 00 00 80 01 C0 00",
			"0C 00 05 00 60 AF 3B 03 24 FD FF FE C0 FE",
			"24 00 05 00 40 42 3E 03 02 80 CD B4 04 03 15 00 00 46 6F 72 6D 73 2E 43 6F 6D 6D 61 6E 64 42 75 74 74 6F 6E 2E 31 00 00 00 00 54 00 00 00 00 00 00 00 00 00 00 00",
			"22 00 05 00 10 4E 3E 03 02 00 4C CC 04 03 12 00 00 46 6F 72 6D 73 2E 53 70 69 6E 42 75 74 74 6F 6E 2E 31 00 54 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00",
			"20 00 05 00 E0 41 3E 03 02 00 FC 0B 05 03 10 00 00 46 6F 72 6D 73 2E 43 6F 6D 62 6F 42 6F 78 2E 31 00 74 00 00 00 4C 00 00 00 00 00 00 00 00 00 00 00",
			"24 00 05 00 00 4C AF 03 02 80 E1 93 05 03 14 00 00 46 6F 72 6D 73 2E 4F 70 74 69 6F 6E 42 75 74 74 6F 6E 2E 31 00 C0 00 00 00 70 00 00 00 00 00 00 00 00 00 00 00",
			"20 00 05 00 E0 A4 28 04 02 80 EA 93 05 03 10 00 00 46 6F 72 6D 73 2E 43 68 65 63 6B 42 6F 78 2E 31 00 30 01 00 00 6C 00 00 00 00 00 00 00 00 00 00 00",
			"1C 00 05 00 30 40 3E 03 02 00 CC B4 04 03 0D 00 00 46 6F 72 6D 73 2E 4C 61 62 65 6C 2E 31 9C 01 00 00 54 00 00 00 00 00 00 00 00 00 00 00",
			"1E 00 05 00 B0 A4 28 04 02 00 D0 0A 05 03 0F 00 00 46 6F 72 6D 73 2E 4C 69 73 74 42 6F 78 2E 31 F0 01 00 00 48 00 00 00 00 00 00 00 00 00 00 00",
			"24 00 05 00 C0 AF 3B 03 02 80 D1 0A 05 03 14 00 00 46 6F 72 6D 73 2E 54 6F 67 67 6C 65 42 75 74 74 6F 6E 2E 31 00 38 02 00 00 6C 00 00 00 00 00 00 00 00 00 00 00",
			"1E 00 05 00 90 AF 3B 03 02 80 D4 0A 05 03 0F 00 00 46 6F 72 6D 73 2E 54 65 78 74 42 6F 78 2E 31 A4 02 00 00 48 00 00 00 00 00 00 00 00 00 00 00",
			"24 00 05 00 60 40 3E 03 02 00 D6 0A 05 03 14 00 00 46 6F 72 6D 73 2E 54 6F 67 67 6C 65 42 75 74 74 6F 6E 2E 31 00 EC 02 00 00 6C 00 00 00 00 00 00 00 00 00 00 00",
			"20 00 05 00 20 4D 3E 03 02 00 D9 0A 05 03 11 00 00 46 6F 72 6D 73 2E 53 63 72 6F 6C 6C 42 61 72 2E 31 58 03 00 00 20 00 00 00 00 00 00 00 00 00 00 00",
			"20 00 05 00 00 AF 28 04 02 80 31 AC 04 03 10 00 00 53 68 65 6C 6C 2E 45 78 70 6C 6F 72 65 72 2E 32 00 78 03 00 00 AC 00 00 00 00 00 00 00 00 00 00 00",
		};

		for (int i = 0; i < rawData.length; i++) {
			confirmRead(hr(rawData[i]), i);
		}
	}

	private static void confirmRead(byte[] data, int i) {
		RecordInputStream in = TestcaseRecordInputStream.create(EORSR_SID, data);

		EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in, data.length);
		byte[] ser2 = rec.serialize();
		confirmRecordEncoding("Test record " + i, EORSR_SID, data, ser2);
	}

	@SuppressWarnings("squid:S2699")
	@Test
	void testVisioDrawing_bug46199() {
		/*
		 * taken from ftPictFmla sub-record in attachment 22860 (stream offset 0x768F).<br>
		 * Note that the since the string length is zero, there is no unicode flag byte
		 */
		byte[] data46199 = hr(
				  "0E 00 "
				+ "05 00 "
				+ "28 25 A3 01 "
				+ "02 6C D1 34 02 "
				+ "03 00 00 "
				+ "0F CB E8 00");
		RecordInputStream in = TestcaseRecordInputStream.create(EORSR_SID, data46199);

		// bug 22860 - Not enough data (3) to read requested (4) bytes
		EmbeddedObjectRefSubRecord rec  = new EmbeddedObjectRefSubRecord(in, data46199.length);
		byte[] ser2 = rec.serialize();
		confirmRecordEncoding(EORSR_SID, data46199, ser2);
	}
}
