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

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

import java.util.Arrays;

import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeUtil;
import org.junit.jupiter.api.Test;

/**
 * Tests CellRange operations.
 */
final class TestCellRange {
	private static final CellRangeAddress biggest     = createCR( 0, -1, 0,-1);
	private static final CellRangeAddress tenthColumn = createCR( 0, -1,10,10);
	private static final CellRangeAddress tenthRow    = createCR(10, 10, 0,-1);
	private static final CellRangeAddress box10x10    = createCR( 0, 10, 0,10);
	private static final CellRangeAddress box9x9      = createCR( 0,  9, 0, 9);
	private static final CellRangeAddress box10to20c  = createCR( 0, 10,10,20);
	private static final CellRangeAddress oneCell     = createCR(10, 10,10,10);

	private static final CellRangeAddress[] sampleRanges = {
		biggest, tenthColumn, tenthRow, box10x10, box9x9, box10to20c, oneCell,
	};

	/** cross-reference of {@code contains()} operations for sampleRanges against itself */
	private static final boolean [][] containsExpectedResults =
    {
	//               biggest, tenthColumn, tenthRow, box10x10, box9x9, box10to20c, oneCell
	/*biggest    */ {true,       true ,    true ,    true ,    true ,      true ,  true},
	/*tenthColumn*/ {false,      true ,    false,    false,    false,      false,  true},
	/*tenthRow   */ {false,      false,    true ,    false,    false,      false,  true},
	/*box10x10   */ {false,      false,    false,    true ,    true ,      false,  true},
	/*box9x9     */ {false,      false,    false,    false,    true ,      false, false},
	/*box10to20c */ {false,      false,    false,    false,    false,      true ,  true},
	/*oneCell    */ {false,      false,    false,    false,    false,      false,  true},
     } ;

	/**
	 * @param lastRow pass -1 for max row index
	 * @param lastCol pass -1 for max col index
	 */
	private static CellRangeAddress createCR(int firstRow, int lastRow, int firstCol, int lastCol) {
		// max row & max col limit as per BIFF8
		return new CellRangeAddress(
				firstRow,
				lastRow == -1 ? 0xFFFF : lastRow,
				firstCol,
				lastCol == -1 ? 0x00FF : lastCol);
	}

	@Test
	void testContainsMethod()
	{
		CellRangeAddress [] ranges = sampleRanges;
		for(int i=0; i!=ranges.length;i++)
		{
			for(int j=0; j!=ranges.length;j++)
			{
				boolean expectedResult = containsExpectedResults[i][j];
				assertEquals(expectedResult, CellRangeUtil.contains(ranges[i], ranges[j]), "("+i+","+j+"): ");
			}
		}
	}

	private static final CellRangeAddress col1     = createCR( 0, -1, 1,1);
	private static final CellRangeAddress col2     = createCR( 0, -1, 2,2);
	private static final CellRangeAddress row1     = createCR( 1,  1, 0,-1);
	private static final CellRangeAddress row2     = createCR( 2,  2, 0,-1);

	private static final CellRangeAddress box0     = createCR( 0, 2, 0,2);
	private static final CellRangeAddress box1     = createCR( 0, 1, 0,1);
	private static final CellRangeAddress box2     = createCR( 0, 1, 2,3);
	private static final CellRangeAddress box3     = createCR( 2, 3, 0,1);
	private static final CellRangeAddress box4     = createCR( 2, 3, 2,3);
	private static final CellRangeAddress box5     = createCR( 1, 3, 1,3);

	@Test
	void testHasSharedBorderMethod() {
		assertFalse(CellRangeUtil.hasExactSharedBorder(col1, col1));
		assertFalse(CellRangeUtil.hasExactSharedBorder(col2, col2));
		assertTrue(CellRangeUtil.hasExactSharedBorder(col1, col2));
		assertTrue(CellRangeUtil.hasExactSharedBorder(col2, col1));

		assertFalse(CellRangeUtil.hasExactSharedBorder(row1, row1));
		assertFalse(CellRangeUtil.hasExactSharedBorder(row2, row2));
		assertTrue(CellRangeUtil.hasExactSharedBorder(row1, row2));
		assertTrue(CellRangeUtil.hasExactSharedBorder(row2, row1));

		assertFalse(CellRangeUtil.hasExactSharedBorder(row1, col1));
		assertFalse(CellRangeUtil.hasExactSharedBorder(row1, col2));
		assertFalse(CellRangeUtil.hasExactSharedBorder(col1, row1));
		assertFalse(CellRangeUtil.hasExactSharedBorder(col2, row1));
		assertFalse(CellRangeUtil.hasExactSharedBorder(row2, col1));
		assertFalse(CellRangeUtil.hasExactSharedBorder(row2, col2));
		assertFalse(CellRangeUtil.hasExactSharedBorder(col1, row2));
		assertFalse(CellRangeUtil.hasExactSharedBorder(col2, row2));
		assertTrue(CellRangeUtil.hasExactSharedBorder(col2, col1));

		assertFalse(CellRangeUtil.hasExactSharedBorder(box1, box1));
		assertTrue(CellRangeUtil.hasExactSharedBorder(box1, box2));
		assertTrue(CellRangeUtil.hasExactSharedBorder(box1, box3));
		assertFalse(CellRangeUtil.hasExactSharedBorder(box1, box4));

		assertTrue(CellRangeUtil.hasExactSharedBorder(box2, box1));
		assertFalse(CellRangeUtil.hasExactSharedBorder(box2, box2));
		assertFalse(CellRangeUtil.hasExactSharedBorder(box2, box3));
		assertTrue(CellRangeUtil.hasExactSharedBorder(box2, box4));

		assertTrue(CellRangeUtil.hasExactSharedBorder(box3, box1));
		assertFalse(CellRangeUtil.hasExactSharedBorder(box3, box2));
		assertFalse(CellRangeUtil.hasExactSharedBorder(box3, box3));
		assertTrue(CellRangeUtil.hasExactSharedBorder(box3, box4));

		assertFalse(CellRangeUtil.hasExactSharedBorder(box4, box1));
		assertTrue(CellRangeUtil.hasExactSharedBorder(box4, box2));
		assertTrue(CellRangeUtil.hasExactSharedBorder(box4, box3));
		assertFalse(CellRangeUtil.hasExactSharedBorder(box4, box4));
	}

	@Test
	void testIntersectMethod() {
		assertEquals(CellRangeUtil.OVERLAP, CellRangeUtil.intersect(box0, box5));
		assertEquals(CellRangeUtil.OVERLAP, CellRangeUtil.intersect(box5, box0));
		assertEquals(CellRangeUtil.NO_INTERSECTION, CellRangeUtil.intersect(box1, box4));
		assertEquals(CellRangeUtil.NO_INTERSECTION, CellRangeUtil.intersect(box4, box1));
		assertEquals(CellRangeUtil.NO_INTERSECTION, CellRangeUtil.intersect(box2, box3));
		assertEquals(CellRangeUtil.NO_INTERSECTION, CellRangeUtil.intersect(box3, box2));
		assertEquals(CellRangeUtil.INSIDE, CellRangeUtil.intersect(box0, box1));
		assertEquals(CellRangeUtil.INSIDE, CellRangeUtil.intersect(box0, box0));
		assertEquals(CellRangeUtil.ENCLOSES, CellRangeUtil.intersect(box1, box0));
		assertEquals(CellRangeUtil.INSIDE, CellRangeUtil.intersect(tenthColumn, oneCell));
		assertEquals(CellRangeUtil.ENCLOSES, CellRangeUtil.intersect(oneCell, tenthColumn));
		assertEquals(CellRangeUtil.OVERLAP, CellRangeUtil.intersect(tenthColumn, tenthRow));
		assertEquals(CellRangeUtil.OVERLAP, CellRangeUtil.intersect(tenthRow, tenthColumn));
		assertEquals(CellRangeUtil.INSIDE, CellRangeUtil.intersect(tenthColumn, tenthColumn));
		assertEquals(CellRangeUtil.INSIDE, CellRangeUtil.intersect(tenthRow, tenthRow));

		// Bug 55380
		assertEquals(CellRangeUtil.OVERLAP, CellRangeUtil.intersect(
		        CellRangeAddress.valueOf("C1:D2"), CellRangeAddress.valueOf("C2:C3")));
	}

	/**
	 * Cell ranges like the following are valid
	 * =$C:$IV,$B$1:$B$8,$B$10:$B$65536,$A:$A
	 */
	@Test
	void testCreate() {
		CellRangeAddress cr = createCR(0, -1, 2, 255); // $C:$IV

		assertFalse(cr.isFullRowRange(), "isFullRowRange");
		assertTrue(cr.isFullColumnRange(), "isFullColumnRange");

		createCR(0, 7, 1, 1); // $B$1:$B$8

		// bug 44739 - invalid cell range
		createCR(9, -1, 1, 1); // $B$65536

		createCR(0, -1, 0, 0); // $A:$A
	}

	@Test
	void testNumberOfCells() {
		assertEquals(1, oneCell.getNumberOfCells());
		assertEquals(100, box9x9.getNumberOfCells());
		assertEquals(121, box10to20c.getNumberOfCells());
	}

	@SuppressWarnings("RedundantArrayCreation")
	@Test
    void testMergeCellRanges() {
        // no result on empty
        cellRangeTest(new String[]{ });

        // various cases with two ranges
        cellRangeTest(new String[]{"A1:B1", "A2:B2"}, "A1:B2");
        cellRangeTest(new String[]{"A1:B1" }, "A1:B1");
        cellRangeTest(new String[]{"A1:B2", "A2:B2"}, "A1:B2");
        cellRangeTest(new String[]{"A1:B3", "A2:B2"}, "A1:B3");
        cellRangeTest(new String[]{"A1:C1", "A2:B2"}, new String[] {"A1:C1", "A2:B2"});

        // cases with three ranges
        cellRangeTest(new String[]{"A1:A1", "A2:B2", "A1:C1"}, new String[] {"A1:C1", "A2:B2"});
        cellRangeTest(new String[]{"A1:C1", "A2:B2", "A1:A1"}, new String[] {"A1:C1", "A2:B2"});

        // "standard" cases
        // enclose
        cellRangeTest(new String[]{"A1:D4", "B2:C3"}, new String[] {"A1:D4"});
        // inside
        cellRangeTest(new String[]{"B2:C3", "A1:D4"}, new String[] {"A1:D4"});
        cellRangeTest(new String[]{"B2:C3", "A1:D4"}, new String[] {"A1:D4"});
        // disjunct
        cellRangeTest(new String[]{"A1:B2", "C3:D4"}, new String[] {"A1:B2", "C3:D4"});
        cellRangeTest(new String[]{"A1:B2", "A3:D4"}, new String[] {"A1:B2", "A3:D4"});
        // overlap that cannot be merged
        cellRangeTest(new String[]{"C1:D2", "C2:C3"}, new String[] {"C1:D2", "C2:C3"});
        // overlap which could theoretically be merged, but isn't because the implementation was buggy and therefore was removed
        cellRangeTest(new String[]{"A1:C3", "B1:D3"}, new String[] {"A1:C3", "B1:D3"}); // could be one region "A1:D3"
        cellRangeTest(new String[]{"A1:C3", "B1:D1"}, new String[] {"A1:C3", "B1:D1"}); // could be one region "A1:D3"
    }

	@SuppressWarnings("RedundantArrayCreation")
	@Test
    void testMergeCellRanges55380() {
        cellRangeTest(new String[]{"C1:D2", "C2:C3"}, new String[] {"C1:D2", "C2:C3"});
        cellRangeTest(new String[]{"A1:C3", "B2:D2"}, new String[] {"A1:C3", "B2:D2"});
        cellRangeTest(new String[]{"C9:D30", "C7:C31"}, new String[] {"C9:D30",  "C7:C31"});
    }

//    void testResolveRangeOverlap() {
//        resolveRangeOverlapTest("C1:D2", "C2:C3");
//    }

    private void cellRangeTest(String[] input, String... expectedOutput) {
        CellRangeAddress[] inputArr = new CellRangeAddress[input.length];
        for(int i = 0;i < input.length;i++) {
            inputArr[i] = CellRangeAddress.valueOf(input[i]);
        }
        CellRangeAddress[] result = CellRangeUtil.mergeCellRanges(inputArr);
        verifyExpectedResult(result, expectedOutput);
    }

//    private void resolveRangeOverlapTest(String a, String b, String...expectedOutput) {
//        CellRangeAddress rangeA = CellRangeAddress.valueOf(a);
//        CellRangeAddress rangeB = CellRangeAddress.valueOf(b);
//        CellRangeAddress[] result = CellRangeUtil.resolveRangeOverlap(rangeA, rangeB);
//        verifyExpectedResult(result, expectedOutput);
//    }

    private void verifyExpectedResult(CellRangeAddress[] result, String... expectedOutput) {
        assertEquals(expectedOutput.length, result.length,
			"\nExpected: " + Arrays.toString(expectedOutput) + "\nHad: " + Arrays.toString(result));
        for(int i = 0;i < expectedOutput.length;i++) {
            assertEquals(expectedOutput[i], result[i].formatAsString(),
				"\nExpected: " + Arrays.toString(expectedOutput) + "\nHad: " + Arrays.toString(result));
        }
    }

	@Test
    void testValueOf() {
        CellRangeAddress cr1 = CellRangeAddress.valueOf("A1:B1");
        assertEquals(0, cr1.getFirstColumn());
        assertEquals(0, cr1.getFirstRow());
        assertEquals(1, cr1.getLastColumn());
        assertEquals(0, cr1.getLastRow());

        CellRangeAddress cr2 = CellRangeAddress.valueOf("B1");
        assertEquals(1, cr2.getFirstColumn());
        assertEquals(0, cr2.getFirstRow());
        assertEquals(1, cr2.getLastColumn());
        assertEquals(0, cr2.getLastRow());
    }
}
