/* ====================================================================
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 <tt>contains()</tt> 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());
    }
}
