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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.IOException;

import org.apache.poi.hssf.HSSFITestDataProvider;
import org.apache.poi.hssf.record.ArrayRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.SharedValueManager;
import org.apache.poi.hssf.record.aggregates.TestSharedValueManager;
import org.apache.poi.ss.usermodel.BaseTestSheetUpdateArrayFormulas;
import org.apache.poi.ss.usermodel.CellRange;
import org.apache.poi.ss.util.CellRangeAddress;
import org.junit.Test;

/**
 * Test array formulas in HSSF
 *
 * @author Yegor Kozlov
 * @author Josh Micich
 */
public final class TestHSSFSheetUpdateArrayFormulas extends BaseTestSheetUpdateArrayFormulas {

    public TestHSSFSheetUpdateArrayFormulas() {
        super(HSSFITestDataProvider.instance);
    }

    // Test methods common with XSSF are in superclass
    // Local methods here test HSSF-specific details of updating array formulas
    @Test
    public void testHSSFSetArrayFormula_singleCell() throws IOException {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet("Sheet1");

        CellRangeAddress range = new CellRangeAddress(2, 2, 2, 2);
        HSSFCell[] cells = sheet.setArrayFormula("SUM(C11:C12*D11:D12)", range).getFlattenedCells();
        assertEquals(1, cells.length);

        // sheet.setArrayFormula creates rows and cells for the designated range
        assertNotNull(sheet.getRow(2));
        HSSFCell cell = sheet.getRow(2).getCell(2);
        assertNotNull(cell);

        assertTrue(cell.isPartOfArrayFormulaGroup());
        //retrieve the range and check it is the same
        assertEquals(range.formatAsString(), cell.getArrayFormulaRange().formatAsString());

        FormulaRecordAggregate agg = (FormulaRecordAggregate)cell.getCellValueRecord();
        assertEquals(range.formatAsString(), agg.getArrayFormulaRange().formatAsString());
        assertTrue(agg.isPartOfArrayFormula());
        
        workbook.close();
    }

    /**
     * Makes sure the internal state of HSSFSheet is consistent after removing array formulas
     */
    @Test
    public void testAddRemoveArrayFormulas_recordUpdates() throws IOException {
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet s = wb.createSheet("Sheet1");

        CellRange<HSSFCell> cr = s.setArrayFormula("123", CellRangeAddress.valueOf("B5:C6"));
        Record[] recs;
        int ix;
        recs = RecordInspector.getRecords(s, 0);
        ix = findRecordOfType(recs, ArrayRecord.class, 0);
        confirmRecordClass(recs, ix-1, FormulaRecord.class);
        confirmRecordClass(recs, ix+1, FormulaRecord.class);
        confirmRecordClass(recs, ix+2, FormulaRecord.class);
        confirmRecordClass(recs, ix+3, FormulaRecord.class);
        // just one array record
        assertTrue(findRecordOfType(recs, ArrayRecord.class, ix+1) < 0);

        s.removeArrayFormula(cr.getTopLeftCell());

        // Make sure the array formula has been removed properly

        recs = RecordInspector.getRecords(s, 0);
        assertTrue(findRecordOfType(recs, ArrayRecord.class, 0) < 0);
        assertTrue(findRecordOfType(recs, FormulaRecord.class, 0) < 0);
        RowRecordsAggregate rra = s.getSheet().getRowsAggregate();
        SharedValueManager svm = TestSharedValueManager.extractFromRRA(rra);
        if (svm.getArrayRecord(4, 1) != null) {
            fail("Array record was not cleaned up properly.");
        }
        
        wb.close();
    }

    private static void confirmRecordClass(Record[] recs, int index, Class<? extends Record> cls) {
        if (recs.length <= index) {
            fail("Expected (" + cls.getName() + ") at index "
                + index + " but array length is " + recs.length + ".");
        }
        assertEquals(cls, recs[index].getClass());
    }
    /**
     * @return <tt>-1<tt> if not found
     */
    private static int findRecordOfType(Record[] recs, Class<?> type, int fromIndex) {
        for (int i=fromIndex; i<recs.length; i++) {
            if (type.isInstance(recs[i])) {
                return i;
            }
        }
        return -1;
    }
}
