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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.util.Iterator;

import org.apache.poi.ss.ITestDataProvider;
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
import org.junit.jupiter.api.Test;

/**
 * A base class for testing implementations of
 * {@link org.apache.poi.ss.usermodel.Row}
 */
public abstract class BaseTestRow {

    protected final ITestDataProvider _testDataProvider;

    protected BaseTestRow(ITestDataProvider testDataProvider) {
        _testDataProvider = testDataProvider;
    }

    @Test
    void testLastAndFirstColumns() throws IOException {
        Workbook workbook = _testDataProvider.createWorkbook();
        Sheet sheet = workbook.createSheet();
        Row row = sheet.createRow(0);
        assertEquals(-1, row.getFirstCellNum());
        assertEquals(-1, row.getLastCellNum());

        //getting cells from an empty row should returns null
        for(int i=0; i < 10; i++) assertNull(row.getCell(i));

        row.createCell(2);
        assertEquals(2, row.getFirstCellNum());
        assertEquals(3, row.getLastCellNum());

        row.createCell(1);
        assertEquals(1, row.getFirstCellNum());
        assertEquals(3, row.getLastCellNum());

        // check the exact case reported in 'bug' 43901 - notice that the cellNum is '0' based
        row.createCell(3);
        assertEquals(1, row.getFirstCellNum());
        assertEquals(4, row.getLastCellNum());
        workbook.close();
    }

    /**
     * Make sure that there is no cross-talk between rows especially with getFirstCellNum and getLastCellNum
     * This test was added in response to bug report 44987.
     */
    @Test
    void testBoundsInMultipleRows() throws IOException {
        Workbook workbook = _testDataProvider.createWorkbook();
        Sheet sheet = workbook.createSheet();
        Row rowA = sheet.createRow(0);

        rowA.createCell(10);
        rowA.createCell(5);
        assertEquals(5, rowA.getFirstCellNum());
        assertEquals(11, rowA.getLastCellNum());

        Row rowB = sheet.createRow(1);
        rowB.createCell(15);
        rowB.createCell(30);
        assertEquals(15, rowB.getFirstCellNum());
        assertEquals(31, rowB.getLastCellNum());

        assertEquals(5, rowA.getFirstCellNum());
        assertEquals(11, rowA.getLastCellNum());
        rowA.createCell(50);
        assertEquals(51, rowA.getLastCellNum());

        assertEquals(31, rowB.getLastCellNum());
        workbook.close();
    }

    @Test
    void testRemoveCell() throws IOException {
        Workbook wb1 = _testDataProvider.createWorkbook();
        {
            Sheet sheet = wb1.createSheet();
            Row row = sheet.createRow(0);

            assertEquals(0, row.getPhysicalNumberOfCells());
            assertEquals(-1, row.getLastCellNum());
            assertEquals(-1, row.getFirstCellNum());

            row.createCell(1);
            assertEquals(2, row.getLastCellNum());
            assertEquals(1, row.getFirstCellNum());
            assertEquals(1, row.getPhysicalNumberOfCells());
            row.createCell(3);
            assertEquals(4, row.getLastCellNum());
            assertEquals(1, row.getFirstCellNum());
            assertEquals(2, row.getPhysicalNumberOfCells());
            row.removeCell(row.getCell(3));
            assertEquals(2, row.getLastCellNum());
            assertEquals(1, row.getFirstCellNum());
            assertEquals(1, row.getPhysicalNumberOfCells());
            row.removeCell(row.getCell(1));
            assertEquals(-1, row.getLastCellNum());
            assertEquals(-1, row.getFirstCellNum());
            assertEquals(0, row.getPhysicalNumberOfCells());
        }

        Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1);
        wb1.close();

        {
            Sheet sheet = wb2.getSheetAt(0);
            Row row = sheet.getRow(0);
            assertEquals(-1, row.getLastCellNum());
            assertEquals(-1, row.getFirstCellNum());
            assertEquals(0, row.getPhysicalNumberOfCells());
        }

        wb2.close();
    }

    @Test
    void testRowBounds() throws IOException {
        int maxRowNum = _testDataProvider.getSpreadsheetVersion().getLastRowIndex();
        try (Workbook workbook = _testDataProvider.createWorkbook()) {
            Sheet sheet = workbook.createSheet();
            //Test low row bound
            sheet.createRow(0);
            //Test low row bound exception
            IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> sheet.createRow(-1));
            assertTrue(e.getMessage().startsWith("Invalid row number (-1)"));

            //Test high row bound
            sheet.createRow(maxRowNum);
            //Test high row bound exception
            e = assertThrows(IllegalArgumentException.class, () -> sheet.createRow(maxRowNum + 1));
            assertEquals("Invalid row number (" + (maxRowNum + 1) + ") outside allowable range (0.." + maxRowNum + ")", e.getMessage());
        }
    }

    @Test
    protected void testCellBounds() throws IOException {
        int maxCellNum = _testDataProvider.getSpreadsheetVersion().getLastColumnIndex();
        try (Workbook wb1 = _testDataProvider.createWorkbook()) {
            Sheet sheet = wb1.createSheet();

            Row row1 = sheet.createRow(0);
            //Test low cell bound
            IllegalArgumentException e;
            e = assertThrows(IllegalArgumentException.class, () -> row1.createCell(-1));
            assertTrue(e.getMessage().startsWith("Invalid column index (-1)"));

            //Test high cell bound
            e = assertThrows(IllegalArgumentException.class, () -> row1.createCell(maxCellNum + 1));
            assertTrue(e.getMessage().startsWith("Invalid column index (" + (maxCellNum + 1) + ")"));

            for (int i = 0; i < maxCellNum; i++) {
                row1.createCell(i);
            }
            assertEquals(maxCellNum, row1.getPhysicalNumberOfCells());

            try (Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1)) {
                sheet = wb2.getSheetAt(0);
                Row row2 = sheet.getRow(0);
                assertEquals(maxCellNum, row2.getPhysicalNumberOfCells());
                for (int i = 0; i < maxCellNum; i++) {
                    Cell cell = row2.getCell(i);
                    assertEquals(i, cell.getColumnIndex());
                }
            }
        }
    }

    /**
     * Prior to patch 43901, POI was producing files with the wrong last-column
     * number on the row
     */
    @Test
    void testLastCellNumIsCorrectAfterAddCell_bug43901() throws IOException {
        Workbook workbook = _testDataProvider.createWorkbook();
        Sheet sheet = workbook.createSheet("test");
        Row row = sheet.createRow(0);

        // New row has last col -1
        assertEquals(-1, row.getLastCellNum());
        assertNotEquals(0, row.getLastCellNum(), "Identified bug 43901");

        // Create two cells, will return one higher
        //  than that for the last number
        row.createCell(0);
        assertEquals(1, row.getLastCellNum());
        row.createCell(255);
        assertEquals(256, row.getLastCellNum());
        workbook.close();
    }

    /**
     * Tests for the missing/blank cell policy stuff
     */
    @Test
    void testGetCellPolicy() throws IOException {
        Workbook workbook = _testDataProvider.createWorkbook();
        Sheet sheet = workbook.createSheet("test");
        Row row = sheet.createRow(0);

        // 0 -> string
        // 1 -> num
        // 2 missing
        // 3 missing
        // 4 -> blank
        // 5 -> num
        row.createCell(0).setCellValue("test");
        row.createCell(1).setCellValue(3.2);
        row.createCell(4, CellType.BLANK);
        row.createCell(5).setCellValue(4);

        // First up, no policy given, uses default
        assertEquals(CellType.STRING,  row.getCell(0).getCellType());
        assertEquals(CellType.NUMERIC, row.getCell(1).getCellType());
        assertNull(row.getCell(2));
        assertNull(row.getCell(3));
        assertEquals(CellType.BLANK,   row.getCell(4).getCellType());
        assertEquals(CellType.NUMERIC, row.getCell(5).getCellType());

        // RETURN_NULL_AND_BLANK - same as default
        assertEquals(CellType.STRING,  row.getCell(0, MissingCellPolicy.RETURN_NULL_AND_BLANK).getCellType());
        assertEquals(CellType.NUMERIC, row.getCell(1, MissingCellPolicy.RETURN_NULL_AND_BLANK).getCellType());
        assertNull(row.getCell(2, MissingCellPolicy.RETURN_NULL_AND_BLANK));
        assertNull(row.getCell(3, MissingCellPolicy.RETURN_NULL_AND_BLANK));
        assertEquals(CellType.BLANK,   row.getCell(4, MissingCellPolicy.RETURN_NULL_AND_BLANK).getCellType());
        assertEquals(CellType.NUMERIC, row.getCell(5, MissingCellPolicy.RETURN_NULL_AND_BLANK).getCellType());

        // RETURN_BLANK_AS_NULL - nearly the same
        assertEquals(CellType.STRING,  row.getCell(0, MissingCellPolicy.RETURN_BLANK_AS_NULL).getCellType());
        assertEquals(CellType.NUMERIC, row.getCell(1, MissingCellPolicy.RETURN_BLANK_AS_NULL).getCellType());
        assertNull(row.getCell(2, MissingCellPolicy.RETURN_BLANK_AS_NULL));
        assertNull(row.getCell(3, MissingCellPolicy.RETURN_BLANK_AS_NULL));
        assertNull(row.getCell(4, MissingCellPolicy.RETURN_BLANK_AS_NULL));
        assertEquals(CellType.NUMERIC, row.getCell(5, MissingCellPolicy.RETURN_BLANK_AS_NULL).getCellType());

        // CREATE_NULL_AS_BLANK - creates as needed
        assertEquals(CellType.STRING,  row.getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getCellType());
        assertEquals(CellType.NUMERIC, row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK).getCellType());
        assertEquals(CellType.BLANK,   row.getCell(2, MissingCellPolicy.CREATE_NULL_AS_BLANK).getCellType());
        assertEquals(CellType.BLANK,   row.getCell(3, MissingCellPolicy.CREATE_NULL_AS_BLANK).getCellType());
        assertEquals(CellType.BLANK,   row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK).getCellType());
        assertEquals(CellType.NUMERIC, row.getCell(5, MissingCellPolicy.CREATE_NULL_AS_BLANK).getCellType());

        // Check created ones get the right column
        assertEquals(0, row.getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).getColumnIndex());
        assertEquals(1, row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK).getColumnIndex());
        assertEquals(2, row.getCell(2, MissingCellPolicy.CREATE_NULL_AS_BLANK).getColumnIndex());
        assertEquals(3, row.getCell(3, MissingCellPolicy.CREATE_NULL_AS_BLANK).getColumnIndex());
        assertEquals(4, row.getCell(4, MissingCellPolicy.CREATE_NULL_AS_BLANK).getColumnIndex());
        assertEquals(5, row.getCell(5, MissingCellPolicy.CREATE_NULL_AS_BLANK).getColumnIndex());


        // Now change the cell policy on the workbook, check
        //  that that is now used if no policy given
        workbook.setMissingCellPolicy(MissingCellPolicy.RETURN_BLANK_AS_NULL);

        assertEquals(CellType.STRING,  row.getCell(0).getCellType());
        assertEquals(CellType.NUMERIC, row.getCell(1).getCellType());
        assertNull(row.getCell(2));
        assertNull(row.getCell(3));
        assertNull(row.getCell(4));
        assertEquals(CellType.NUMERIC, row.getCell(5).getCellType());

        workbook.close();
    }

    @Test
    protected void testRowHeight() throws IOException {
        Workbook wb1 = _testDataProvider.createWorkbook();
        Sheet sheet = wb1.createSheet();
        Row row1 = sheet.createRow(0);

        assertEquals(sheet.getDefaultRowHeight(), row1.getHeight());

        sheet.setDefaultRowHeightInPoints(20);
        row1.setHeight((short)-1); //reset the row height
        assertEquals(20.0f, row1.getHeightInPoints(), 0F);
        assertEquals(20*20, row1.getHeight());

        Row row2 = sheet.createRow(1);
        assertEquals(sheet.getDefaultRowHeight(), row2.getHeight());
        row2.setHeight((short)310);
        assertEquals(310, row2.getHeight());
        assertEquals(310F/20, row2.getHeightInPoints(), 0F);

        Row row3 = sheet.createRow(2);
        row3.setHeightInPoints(25.5f);
        assertEquals((short)(25.5f*20), row3.getHeight());
        assertEquals(25.5f, row3.getHeightInPoints(), 0F);

        Row row4 = sheet.createRow(3);
        assertFalse(row4.getZeroHeight());
        row4.setZeroHeight(true);
        assertTrue(row4.getZeroHeight());

        Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1);
        wb1.close();
        sheet = wb2.getSheetAt(0);

        row1 = sheet.getRow(0);
        row2 = sheet.getRow(1);
        row3 = sheet.getRow(2);
        row4 = sheet.getRow(3);
        assertEquals(20.0f, row1.getHeightInPoints(), 0F);
        assertEquals(20*20, row1.getHeight());

        assertEquals(310, row2.getHeight());
        assertEquals(310F/20, row2.getHeightInPoints(), 0F);

        assertEquals((short)(25.5f*20), row3.getHeight());
        assertEquals(25.5f, row3.getHeightInPoints(), 0F);

        assertFalse(row1.getZeroHeight());
        assertFalse(row2.getZeroHeight());
        assertFalse(row3.getZeroHeight());
        assertTrue(row4.getZeroHeight());
        wb2.close();
    }

    /**
     * Test adding cells to a row in various places and see if we can find them again.
     */
    @Test
    void testCellIterator() throws IOException {
        Workbook wb = _testDataProvider.createWorkbook();
        Sheet sheet = wb.createSheet();
        Row row = sheet.createRow(0);

        // One cell at the beginning
        Cell cell1 = row.createCell(1);
        Iterator<Cell> it = row.cellIterator();
        assertTrue(it.hasNext());
        assertSame(cell1, it.next());
        assertFalse(it.hasNext());

        // Add another cell at the end
        Cell cell2 = row.createCell(99);
        it = row.cellIterator();
        assertTrue(it.hasNext());
        assertSame(cell1, it.next());
        assertTrue(it.hasNext());
        assertSame(cell2, it.next());

        // Add another cell at the beginning
        Cell cell3 = row.createCell(0);
        it = row.cellIterator();
        assertTrue(it.hasNext());
        assertSame(cell3, it.next());
        assertTrue(it.hasNext());
        assertSame(cell1, it.next());
        assertTrue(it.hasNext());
        assertSame(cell2, it.next());

        // Replace cell1
        Cell cell4 = row.createCell(1);
        it = row.cellIterator();
        assertTrue(it.hasNext());
        assertSame(cell3, it.next());
        assertTrue(it.hasNext());
        assertSame(cell4, it.next());
        assertTrue(it.hasNext());
        assertSame(cell2, it.next());
        assertFalse(it.hasNext());

        // Add another cell, specifying the cellType
        Cell cell5 = row.createCell(2, CellType.STRING);
        it = row.cellIterator();
        assertNotNull(cell5);
        assertTrue(it.hasNext());
        assertSame(cell3, it.next());
        assertTrue(it.hasNext());
        assertSame(cell4, it.next());
        assertTrue(it.hasNext());
        assertSame(cell5, it.next());
        assertTrue(it.hasNext());
        assertSame(cell2, it.next());
        assertEquals(CellType.STRING, cell5.getCellType());
        wb.close();
    }

    @Test
    void testRowStyle() throws IOException {
       Workbook wb1 = _testDataProvider.createWorkbook();
       Sheet sheet = wb1.createSheet("test");
       Row row1 = sheet.createRow(0);
       Row row2 = sheet.createRow(1);

       // Won't be styled currently
        assertFalse(row1.isFormatted());
        assertFalse(row2.isFormatted());
        assertNull(row1.getRowStyle());
        assertNull(row2.getRowStyle());

       // Style one
       CellStyle style = wb1.createCellStyle();
       style.setDataFormat((short)4);
       row2.setRowStyle(style);

       // Check
        assertFalse(row1.isFormatted());
        assertTrue(row2.isFormatted());
        assertNull(row1.getRowStyle());
       assertEquals(style, row2.getRowStyle());

       // Save, load and re-check
       Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1);
       wb1.close();

       sheet = wb2.getSheetAt(0);

       row1 = sheet.getRow(0);
       row2 = sheet.getRow(1);
       style = wb2.getCellStyleAt(style.getIndex());

        assertFalse(row1.isFormatted());
        assertTrue(row2.isFormatted());
        assertNull(row1.getRowStyle());
       assertEquals(style, row2.getRowStyle());
       assertEquals(4, style.getDataFormat());

       wb2.close();
    }

    @Test
    protected void testCellShiftingRight() {
        Workbook wb = _testDataProvider.createWorkbook();
        Sheet sheet = wb.createSheet("sheet1");
        Row row = sheet.createRow(0);
        row.createCell(0, CellType.NUMERIC).setCellValue(0);
        row.createCell(1, CellType.NUMERIC).setCellValue(1);
        row.createCell(2, CellType.NUMERIC).setCellValue(2);//C
        row.createCell(3, CellType.NUMERIC).setCellValue(3);//D
        row.createCell(4, CellType.NUMERIC).setCellValue(4);//E
        row.createCell(5, CellType.NUMERIC).setCellValue(5);//F
        row.createCell(6, CellType.NUMERIC).setCellValue(6);//G

        assertThrows(IllegalArgumentException.class, () -> row.shiftCellsLeft(6, 4, 2),  "range [6-4] is illegal");
        row.shiftCellsRight(2, 4, 1);
        //should be [0.0, 1.0, null, 2.0, 3.0, 4.0, 6.0, null]

        Cell h1 = row.getCell(7);
        assertNull(h1);
        Cell g1 = row.getCell(6);
        assertEquals(6, g1.getNumericCellValue(), 0.01);
        Cell f1 = row.getCell(5);
        assertEquals(4, f1.getNumericCellValue(), 0.01);
        Cell e1 = row.getCell(4);
        assertEquals(3, e1.getNumericCellValue(), 0.01);
        Cell d1 = row.getCell(3);
        assertEquals(2, d1.getNumericCellValue(), 0.01);
        Cell c1 = row.getCell(2);
        assertNull(c1);
    }

    @Test
    protected void testCellShiftingLeft() {
        Workbook wb = _testDataProvider.createWorkbook();
        Sheet sheet = wb.createSheet("sheet1");
        Row row = sheet.createRow(0);
        row.createCell(0, CellType.NUMERIC).setCellValue(0);
        row.createCell(1, CellType.NUMERIC).setCellValue(1);
        row.createCell(2, CellType.NUMERIC).setCellValue(2);//C
        row.createCell(3, CellType.NUMERIC).setCellValue(3);//D
        row.createCell(4, CellType.NUMERIC).setCellValue(4);//E
        row.createCell(5, CellType.NUMERIC).setCellValue(5);//F
        row.createCell(6, CellType.NUMERIC).setCellValue(6);//G

        assertThrows(IllegalArgumentException.class, () -> row.shiftCellsLeft(4, 6, -2), "step = -1 is illegal");
        row.shiftCellsLeft(4, 6, 2);
        //should be [0.0, 1.0, 4.0, 5.0, 6.0, null, null, null]

        Cell b1 = row.getCell(1);
        assertEquals(1, b1.getNumericCellValue(), 0.01);
        Cell c1 = row.getCell(2);
        assertEquals(4, c1.getNumericCellValue(), 0.01);
        Cell d1 = row.getCell(3);
        assertEquals(5, d1.getNumericCellValue(), 0.01);
        Cell e1 = row.getCell(4);
        assertEquals(6, e1.getNumericCellValue(), 0.01);
        Cell f1 = row.getCell(5);
        assertNull(f1);
    }

    @Test
    void testLastRowEmptySheet() {
        Workbook wb = _testDataProvider.createWorkbook();
        Sheet sheet = wb.createSheet("sheet1");

        assertEquals(-1, sheet.getLastRowNum(), "Sheet without rows should return -1 as lastRowNum");
        Row row = sheet.createRow(0);
        assertNotNull(row);

        assertEquals(0, sheet.getLastRowNum(), "Sheet with one row should return 0 as lastRowNum");
    }

    @Test
    void testFirstRowEmptySheet() {
        Workbook wb = _testDataProvider.createWorkbook();
        Sheet sheet = wb.createSheet("sheet1");

        assertEquals(-1, sheet.getFirstRowNum(), "Sheet without rows should return -1 as firstRowNum");
        Row row = sheet.createRow(0);
        assertNotNull(row);

        assertEquals(0, sheet.getFirstRowNum(), "Sheet with one row should return 0 as firstRowNum");
    }
}
