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

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

import java.io.IOException;

import org.apache.poi.ss.usermodel.BaseTestXSheet;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.SXSSFITestDataProvider;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.After;
import org.junit.Test;


public final class TestSXSSFSheet extends BaseTestXSheet {

    public TestSXSSFSheet() {
        super(SXSSFITestDataProvider.instance);
    }


    @After
    public void tearDown(){
        SXSSFITestDataProvider.instance.cleanup();
    }
    
    @Override
    protected void trackColumnsForAutoSizingIfSXSSF(Sheet sheet) {
        SXSSFSheet sxSheet = (SXSSFSheet) sheet;
        sxSheet.trackAllColumnsForAutoSizing();
    }


    /**
     * cloning of sheets is not supported in SXSSF
     */
    @Override
    @Test
    public void cloneSheet() throws IOException {
        thrown.expect(RuntimeException.class);
        thrown.expectMessage("NotImplemented");
        super.cloneSheet();
    }

    @Override
    @Test
    public void cloneSheetMultipleTimes() throws IOException {
        thrown.expect(RuntimeException.class);
        thrown.expectMessage("NotImplemented");
        super.cloneSheetMultipleTimes();
    }
    
    /**
     * shifting rows is not supported in SXSSF
     */
    @Override
    @Test
    public void shiftMerged() throws IOException {
        thrown.expect(RuntimeException.class);
        thrown.expectMessage("NotImplemented");
        super.shiftMerged();
    }

    /**
     *  Bug 35084: cloning cells with formula
     *
     *  The test is disabled because cloning of sheets is not supported in SXSSF
     */
    @Override
    @Test
    public void bug35084() throws IOException {
        thrown.expect(RuntimeException.class);
        thrown.expectMessage("NotImplemented");
        super.bug35084();
    }

    @Test
    public void getCellComment() throws IOException {
        // TODO: reading cell comments via Sheet does not work currently as it tries 
        // to access the underlying sheet for this, but comments are stored as
        // properties on Cells...
    }
    
    @Override
    @Test
    public void defaultColumnStyle() {
        //TODO column styles are not yet supported by XSSF
    }

    @Test
    public void overrideFlushedRows() throws IOException {
        Workbook wb = new SXSSFWorkbook(3);
        try {
            Sheet sheet = wb.createSheet();
    
            sheet.createRow(1);
            sheet.createRow(2);
            sheet.createRow(3);
            sheet.createRow(4);
    
            thrown.expect(Throwable.class);
            thrown.expectMessage("Attempting to write a row[1] in the range [0,1] that is already written to disk.");
            sheet.createRow(1);
        } finally {
            wb.close();
        }
    }

    @Test
    public void overrideRowsInTemplate() throws IOException {
        XSSFWorkbook template = new XSSFWorkbook();
        template.createSheet().createRow(1);

        Workbook wb = new SXSSFWorkbook(template);
        try {
            Sheet sheet = wb.getSheetAt(0);
    
            try {
                sheet.createRow(1);
                fail("expected exception");
            } catch (Throwable e){
                assertEquals("Attempting to write a row[1] in the range [0,1] that is already written to disk.", e.getMessage());
            }
            try {
                sheet.createRow(0);
                fail("expected exception");
            } catch (Throwable e){
                assertEquals("Attempting to write a row[0] in the range [0,1] that is already written to disk.", e.getMessage());
            }
            sheet.createRow(2);
        } finally {
            wb.close();
            template.close();
        }
    }

    @Test
    public void changeRowNum() throws IOException {
        SXSSFWorkbook wb = new SXSSFWorkbook(3);
        SXSSFSheet sheet = wb.createSheet();
        SXSSFRow row0 = sheet.createRow(0);
        SXSSFRow row1 = sheet.createRow(1);
        sheet.changeRowNum(row0, 2);
        
        assertEquals("Row 1 knows its row number", 1, row1.getRowNum());
        assertEquals("Row 2 knows its row number", 2, row0.getRowNum());
        assertEquals("Sheet knows Row 1's row number", 1, sheet.getRowNum(row1));
        assertEquals("Sheet knows Row 2's row number", 2, sheet.getRowNum(row0));
        assertEquals("Sheet row iteratation order should be ascending", row1, sheet.iterator().next());
        
        wb.close();
    }
}
