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


import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertSame;

import java.io.IOException;
import java.io.InputStream;

import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

/**
 * Tests that the helper methods on RecordContainer work properly
 */
public final class TestRecordContainer {
    private HSLFSlideShowImpl hss;
	private RecordContainer recordContainer;
    private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance();

    @BeforeEach
    void setUp() throws IOException {
        // Find a real RecordContainer record
        InputStream is = slTests.openResourceAsStream("basic_test_ppt_file.ppt");
        hss = new HSLFSlideShowImpl(is);
        is.close();

        Record[] r = hss.getRecords();
        for ( org.apache.poi.hslf.record.Record rec : r) {
            if(rec instanceof RecordContainer) {
                recordContainer = (RecordContainer)rec;
                return;
            }
        }
    }

    @AfterEach
    void closeResources() throws IOException {
        hss.close();
    }

	@Test
	void testIsAnAtom() {
		assertFalse( recordContainer.isAnAtom() );
	}

    @Test
	void testAppendChildRecord() {
		// Grab records for testing with
		Record r = recordContainer.getChildRecords()[0];
		Record rb = recordContainer.getChildRecords()[1];
		Record rc = recordContainer.getChildRecords()[2];
		Record rd = recordContainer.getChildRecords()[3];

		// Start with an empty set
		Record[] rs = new Record[0];
		recordContainer._children = rs;
		recordContainer.appendChildRecord(r);
		Record[] nrs = recordContainer.getChildRecords();

		assertEquals(1, nrs.length);
		assertEquals(r, nrs[0]);

		// Now start with one with 3 entries
		rs = new Record[3];
		recordContainer._children = rs;
		rs[0] = rb;
		rs[1] = rc;
		rs[2] = rd;

		recordContainer.appendChildRecord(r);
		nrs = recordContainer.getChildRecords();

		assertEquals(4, nrs.length);
		assertEquals(rb, nrs[0]);
		assertEquals(rc, nrs[1]);
		assertEquals(rd, nrs[2]);
		assertEquals(r, nrs[3]);
	}

    @Test
	void testAddChildAfter() {
		// Working with new StyleTextPropAtom
		Record newRecord = new StyleTextPropAtom(0);

		// Try to add after a mid-record
		Record[] cr = recordContainer.getChildRecords();
		Record after = cr[2];
		Record before = cr[3];

		recordContainer.addChildAfter(newRecord, after);
		Record[] ncr = recordContainer.getChildRecords();

		assertEquals(cr.length+1, ncr.length);
		assertEquals(after, ncr[2]);
		assertEquals(newRecord, ncr[3]);
		assertEquals(before, ncr[4]);

		// Try again at the end
		recordContainer._children = cr;
		after = cr[cr.length-1];

		recordContainer.addChildAfter(newRecord, after);
		ncr = recordContainer.getChildRecords();

		assertEquals(cr.length+1, ncr.length);
		assertEquals(after, ncr[cr.length-1]);
		assertEquals(newRecord, ncr[cr.length]);
	}

    @Test
	void testAddChildBefore() {
		// Working with new StyleTextPropAtom
		Record newRecord = new StyleTextPropAtom(0);

		// Try to add before a mid-record
		Record[] cr = recordContainer.getChildRecords();
		Record before = cr[2];

		recordContainer.addChildBefore(newRecord, before);
		Record[] ncr = recordContainer.getChildRecords();

		assertEquals(cr.length+1, ncr.length);
		assertEquals(newRecord, ncr[2]);
		assertEquals(before, ncr[3]);


		// Try again at the end
		recordContainer._children = cr;
		before = cr[cr.length-1];

		recordContainer.addChildBefore(newRecord, before);
		ncr = recordContainer.getChildRecords();

		assertEquals(cr.length+1, ncr.length);
		assertEquals(newRecord, ncr[cr.length-1]);
		assertEquals(before, ncr[cr.length]);


		// And at the start
		recordContainer._children = cr;
		before = cr[0];

		recordContainer.addChildBefore(newRecord, before);
		ncr = recordContainer.getChildRecords();

		assertEquals(cr.length+1, ncr.length);
		assertEquals(newRecord, ncr[0]);
		assertEquals(before, ncr[1]);
	}

    @Test
    void testRemove() {
        Record[] ch = recordContainer.getChildRecords();
        Record removeRecord = recordContainer.removeChild(ch[0]);
        assertSame(ch[0], removeRecord);
        assertEquals(ch.length-1, recordContainer.getChildRecords().length);
    }
}
