/* ====================================================================
   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 static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.Arrays;
import java.util.List;

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

/**
 * Tests the serialization and deserialization of the ObjRecord class works correctly.
 * Test data taken directly from a real Excel file.
 */
final class TestObjRecord {
    /**
     * OBJ record data containing two sub-records.
     * The data taken directly from a real Excel file.
     *
     * [OBJ]
     *     [ftCmo]
     *     [ftEnd]
     */
    private static final byte[] recdata = HexRead.readFromString(""
            + "15 00 12 00 06 00 01 00 11 60 "
            + "F4 02 41 01 14 10 1F 02 00 00 "
            +"00 00 00 00 00 00"
            // TODO - this data seems to require two extra bytes padding. not sure where original file is.
            // it's not bug 38607 attachment 17639
    );

    /**
     * Hex dump from
     * offset 0x2072 in att 22076 of bug 45133
     */
    private static final byte[] recdataNeedingPadding = HexRead.readFromString(""
            + "5D 00 20 00"
            + "15 00 12 00 00 00 01 00 11 60 00 00 00 00 38 6F CC 03 00 00 00 00 06 00 02 00 00 00 00 00 00 00"
    );

    @Test
    void testLoad() {
        ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdata));

        assertEquals(26, record.getRecordSize() - 4);

        List<SubRecord> subrecords = record.getSubRecords();
        assertEquals(2, subrecords.size() );
        assertTrue(subrecords.get(0) instanceof CommonObjectDataSubRecord);
        assertTrue(subrecords.get(1) instanceof EndSubRecord );

    }

    @Test
    void testStore() {
        ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdata));

        byte [] recordBytes = record.serialize();
        assertEquals(26, recordBytes.length - 4);
        byte[] subData = Arrays.copyOfRange(recordBytes, 4, 4+recdata.length);
        assertArrayEquals(recdata, subData);
    }

    @Test
    void testConstruct() {
        ObjRecord record = new ObjRecord();
        CommonObjectDataSubRecord ftCmo = new CommonObjectDataSubRecord();
        ftCmo.setObjectType( CommonObjectDataSubRecord.OBJECT_TYPE_COMMENT);
        ftCmo.setObjectId( 1024 );
        ftCmo.setLocked( true );
        ftCmo.setPrintable( true );
        ftCmo.setAutofill( true );
        ftCmo.setAutoline( true );
        record.addSubRecord(ftCmo);
        EndSubRecord ftEnd = new EndSubRecord();
        record.addSubRecord(ftEnd);

        //serialize and read again
        byte [] recordBytes = record.serialize();
        //cut off the record header
        byte [] bytes = Arrays.copyOfRange(recordBytes, 4, recordBytes.length);

        record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, bytes));
        List<SubRecord> subrecords = record.getSubRecords();
        assertEquals( 2, subrecords.size() );
        assertTrue( subrecords.get(0) instanceof CommonObjectDataSubRecord);
        assertTrue( subrecords.get(1) instanceof EndSubRecord );
    }

    @Test
    void testReadWriteWithPadding_bug45133() {
        ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(recdataNeedingPadding));
        assertNotEquals(34, record.getRecordSize(), "Identified bug 45133");
        assertEquals(36, record.getRecordSize());

        List<SubRecord> subrecords = record.getSubRecords();
        assertEquals(3, subrecords.size() );
        assertEquals(CommonObjectDataSubRecord.class, subrecords.get(0).getClass());
        assertEquals(GroupMarkerSubRecord.class, subrecords.get(1).getClass());
        assertEquals(EndSubRecord.class, subrecords.get(2).getClass());
    }

    /**
     * Check that ObjRecord tolerates and preserves padding to a 4-byte boundary
     * (normally padding is to a 2-byte boundary).
     */
    @SuppressWarnings("squid:S2699")
    @Test
    void test4BytePadding() {
        // actual data from file saved by Excel 2007
        byte[] data = HexRead.readFromString(""
                + "15 00 12 00  1E 00 01 00  11 60 B4 6D  3C 01 C4 06 "
                + "49 06 00 00  00 00 00 00  00 00 00 00");
        // this data seems to have 2 extra bytes of padding more than usual
        // the total may have been padded to the nearest quad-byte length
        RecordInputStream in = TestcaseRecordInputStream.create(ObjRecord.sid, data);
        // check read OK
        ObjRecord record = new ObjRecord(in);
        // check that it re-serializes to the same data
        byte[] ser = record.serialize();
        confirmRecordEncoding(ObjRecord.sid, data, ser);
    }
}
