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

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.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

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

import org.apache.poi.hssf.record.TestcaseRecordInputStream;
import org.apache.poi.util.LittleEndianOutputStream;
import org.junit.jupiter.api.Test;

final class TestCellRangeAddress {
    static final byte[] data = new byte[] {
            0x02, 0x00, 0x04, 0x00,
            0x00, 0x00, 0x03, 0x00,
    };

    @Test
    void testLoad() {
        CellRangeAddress ref = new CellRangeAddress(
                TestcaseRecordInputStream.create(0x000, data));
        assertEquals(2, ref.getFirstRow());
        assertEquals(4, ref.getLastRow());
        assertEquals(0, ref.getFirstColumn());
        assertEquals(3, ref.getLastColumn());

        assertEquals(8, CellRangeAddress.ENCODED_SIZE);
    }

    @Test
    void testLoadInvalid() {
        RuntimeException e = assertThrows(RuntimeException.class, () ->
            new CellRangeAddress(TestcaseRecordInputStream.create(0x000, new byte[]{(byte) 0x02})));
        assertTrue(e.getMessage().contains("Ran out of data"));
    }

    @Test
    void testStore() throws IOException {
        CellRangeAddress ref = new CellRangeAddress(0, 0, 0, 0);

        byte[] recordBytes;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (LittleEndianOutputStream out = new LittleEndianOutputStream(baos)) {
            // With nothing set
            ref.serialize(out);
            recordBytes = baos.toByteArray();
            assertEquals(recordBytes.length, data.length);
            for (int i = 0; i < data.length; i++) {
                assertEquals(0, recordBytes[i], "At offset " + i);
            }

            // Now set the flags
            ref.setFirstRow((short) 2);
            ref.setLastRow((short) 4);
            ref.setFirstColumn((short) 0);
            ref.setLastColumn((short) 3);

            // Re-test
            baos.reset();
            ref.serialize(out);
            recordBytes = baos.toByteArray();

            assertEquals(recordBytes.length, data.length);
            for (int i = 0; i < data.length; i++) {
                assertEquals(data[i], recordBytes[i], "At offset " + i);
            }
        }
    }

    @Test
    void testCreateIllegal() {
        // for some combinations we expected exceptions
        assertThrows(IllegalArgumentException.class, () -> new CellRangeAddress(1, 0, 0, 0));
        assertThrows(IllegalArgumentException.class, () -> new CellRangeAddress(0, 0, 1, 0));
    }

    @Test
    void testCopy() throws IOException {
        CellRangeAddress ref = new CellRangeAddress(1, 2, 3, 4);
        CellRangeAddress copy = ref.copy();
        assertEquals(ref.toString(), copy.toString());
    }

    @Test
    void testGetEncodedSize() {
        assertEquals(2*CellRangeAddress.ENCODED_SIZE, CellRangeAddress.getEncodedSize(2));
    }

    @Test
    void testFormatAsString() {
        CellRangeAddress ref = new CellRangeAddress(1, 2, 3, 4);

        assertEquals("D2:E3", ref.formatAsString());
        assertEquals("D2:E3", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString());

        assertEquals("sheet1!$D$2:$E$3", ref.formatAsString("sheet1", true));
        assertEquals("sheet1!$D$2:$E$3", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString("sheet1", true));
        assertEquals("sheet1!$D$2:$E$3", CellRangeAddress.valueOf(ref.formatAsString("sheet1", true)).formatAsString("sheet1", true));

        assertEquals("sheet1!D2:E3", ref.formatAsString("sheet1", false));
        assertEquals("sheet1!D2:E3", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString("sheet1", false));
        assertEquals("sheet1!D2:E3", CellRangeAddress.valueOf(ref.formatAsString("sheet1", false)).formatAsString("sheet1", false));

        assertEquals("D2:E3", ref.formatAsString(null, false));
        assertEquals("D2:E3", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString(null, false));
        assertEquals("D2:E3", CellRangeAddress.valueOf(ref.formatAsString(null, false)).formatAsString(null, false));

        assertEquals("$D$2:$E$3", ref.formatAsString(null, true));
        assertEquals("$D$2:$E$3", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString(null, true));
        assertEquals("$D$2:$E$3", CellRangeAddress.valueOf(ref.formatAsString(null, true)).formatAsString(null, true));

        ref = new CellRangeAddress(-1, -1, 3, 4);
        assertEquals("D:E", ref.formatAsString());
        assertEquals("sheet1!$D:$E", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString("sheet1", true));
        assertEquals("sheet1!$D:$E", CellRangeAddress.valueOf(ref.formatAsString("sheet1", true)).formatAsString("sheet1", true));
        assertEquals("$D:$E", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString(null, true));
        assertEquals("$D:$E", CellRangeAddress.valueOf(ref.formatAsString(null, true)).formatAsString(null, true));
        assertEquals("sheet1!D:E", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString("sheet1", false));
        assertEquals("sheet1!D:E", CellRangeAddress.valueOf(ref.formatAsString("sheet1", false)).formatAsString("sheet1", false));

        ref = new CellRangeAddress(1, 2, -1, -1);
        assertEquals("2:3", ref.formatAsString());
        assertEquals("sheet1!$2:$3", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString("sheet1", true));
        assertEquals("sheet1!$2:$3", CellRangeAddress.valueOf(ref.formatAsString("sheet1", true)).formatAsString("sheet1", true));
        assertEquals("$2:$3", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString(null, true));
        assertEquals("$2:$3", CellRangeAddress.valueOf(ref.formatAsString(null, true)).formatAsString(null, true));
        assertEquals("sheet1!2:3", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString("sheet1", false));
        assertEquals("sheet1!2:3", CellRangeAddress.valueOf(ref.formatAsString("sheet1", false)).formatAsString("sheet1", false));

        ref = new CellRangeAddress(1, 1, 2, 2);
        assertEquals("C2", ref.formatAsString());
        assertEquals("sheet1!$C$2", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString("sheet1", true));
        assertEquals("sheet1!$C$2", CellRangeAddress.valueOf(ref.formatAsString("sheet1", true)).formatAsString("sheet1", true));
        assertEquals("$C$2", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString(null, true));
        assertEquals("$C$2", CellRangeAddress.valueOf(ref.formatAsString(null, true)).formatAsString(null, true));
        assertEquals("sheet1!C2", CellRangeAddress.valueOf(ref.formatAsString()).formatAsString("sheet1", false));
        assertEquals("sheet1!C2", CellRangeAddress.valueOf(ref.formatAsString("sheet1", false)).formatAsString("sheet1", false));

        // is this a valid address?
        ref = new CellRangeAddress(-1, -1, -1, -1);
        assertEquals(":", ref.formatAsString());
    }

    @Test
    void testEquals() {
        final CellRangeAddress ref1 = new CellRangeAddress(1, 2, 3, 4);
        final CellRangeAddress ref2 = new CellRangeAddress(1, 2, 3, 4);
        assertEquals(ref1, ref2);

        // Invert first/last row, but refer to same area
        ref2.setFirstRow(2);
        ref2.setLastRow(1);
        assertEquals(ref1, ref2);

        // Invert first/last column, but refer to same area
        ref2.setFirstColumn(4);
        ref2.setLastColumn(3);
        assertEquals(ref1, ref2);

        // Refer to a different area
        assertNotEquals(ref1, new CellRangeAddress(3, 4, 1, 2));
    }

    @Test
    void testGetMinMaxRow() {
        final CellRangeAddress ref = new CellRangeAddress(1, 2, 3, 4);
        assertEquals(1, ref.getMinRow());
        assertEquals(2, ref.getMaxRow());

        ref.setFirstRow(10);
        //now ref is CellRangeAddress(10, 2, 3, 4)
        assertEquals(2, ref.getMinRow());
        assertEquals(10, ref.getMaxRow());
    }

    @Test
    void testGetMinMaxColumn() {
        final CellRangeAddress ref = new CellRangeAddress(1, 2, 3, 4);
        assertEquals(3, ref.getMinColumn());
        assertEquals(4, ref.getMaxColumn());

        ref.setFirstColumn(10);
        //now ref is CellRangeAddress(1, 2, 10, 4)
        assertEquals(4, ref.getMinColumn());
        assertEquals(10, ref.getMaxColumn());
    }

    @Test
    void testIntersects() {
        final CellRangeAddress baseRegion = new CellRangeAddress(0, 1, 0, 1);

        final CellRangeAddress duplicateRegion = new CellRangeAddress(0, 1, 0, 1);
        assertIntersects(baseRegion, duplicateRegion);

        final CellRangeAddress partiallyOverlappingRegion = new CellRangeAddress(1, 2, 1, 2);
        assertIntersects(baseRegion, partiallyOverlappingRegion);

        final CellRangeAddress subsetRegion = new CellRangeAddress(0, 1, 0, 0);
        assertIntersects(baseRegion, subsetRegion);

        final CellRangeAddress supersetRegion = new CellRangeAddress(0, 2, 0, 2);
        assertIntersects(baseRegion, supersetRegion);

        final CellRangeAddress disjointRegion = new CellRangeAddress(10, 11, 10, 11);
        assertNotIntersects(baseRegion, disjointRegion);
    }

    @Test
    void containsRow() {
        final CellRangeAddress region = new CellRangeAddress(10, 12, 3, 5);

        assertFalse(region.containsRow(9));
        assertTrue(region.containsRow(10));
        assertTrue(region.containsRow(11));
        assertTrue(region.containsRow(12));
        assertFalse(region.containsRow(13));
    }

    @Test
    void containsColumn() {
        final CellRangeAddress region = new CellRangeAddress(10, 12, 3, 5);

        assertFalse(region.containsColumn(2));
        assertTrue(region.containsColumn(3));
        assertTrue(region.containsColumn(4));
        assertTrue(region.containsColumn(5));
        assertFalse(region.containsColumn(6));
    }

    @Test
    void iterator() {
        final CellRangeAddress A1_B2 = new CellRangeAddress(0, 1, 0, 1);

        // the cell address iterator iterates in row major order
        final Iterator<CellAddress> iter = A1_B2.iterator();
        assertEquals(new CellAddress(0, 0), iter.next(), "A1");
        assertEquals(new CellAddress(0, 1), iter.next(), "B1");
        assertEquals(new CellAddress(1, 0), iter.next(), "A2");
        assertEquals(new CellAddress(1, 1), iter.next(), "B2");
        assertFalse(iter.hasNext());
        assertThrows(NoSuchElementException.class, iter::next);
        assertThrows(UnsupportedOperationException.class, iter::remove);

        // for each interface
        int count = 0;
        for (final CellAddress addr : A1_B2) {
            assertNotNull(addr);
            count++;
        }
        assertEquals(4, count);
    }

    private static void assertIntersects(CellRangeAddress regionA, CellRangeAddress regionB) {
        if (!(regionA.intersects(regionB) && regionB.intersects(regionA))) {
            final String A = regionA.formatAsString();
            final String B = regionB.formatAsString();
            fail("expected: regions "+A+" and "+B+" intersect");
        }
    }
    private static void assertNotIntersects(CellRangeAddress regionA, CellRangeAddress regionB) {
        if ((regionA.intersects(regionB) || regionB.intersects(regionA))) {
            final String A = regionA.formatAsString();
            final String B = regionB.formatAsString();
            fail("expected: regions "+A+" and "+B+" do not intersect");
        }
    }
}
