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


import java.io.InputStream;
import java.util.Queue;

import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.model.SharedStrings;
import org.apache.poi.xssf.usermodel.XSSFComment;

/**
 * @since 3.16-beta3
 */
@Internal
public class XSSFBSheetHandler extends XSSFBParser {

    private static final int CHECK_ALL_ROWS = -1;

    private final SharedStrings stringsTable;
    private final XSSFSheetXMLHandler.SheetContentsHandler handler;
    private final XSSFBStylesTable styles;
    private final XSSFBCommentsTable comments;
    private final DataFormatter dataFormatter;
    private final boolean formulasNotResults;//TODO: implement this

    private int lastEndedRow = -1;
    private int lastStartedRow = -1;
    private int currentRow;
    private byte[] rkBuffer = new byte[8];
    private XSSFBCellRange hyperlinkCellRange;
    private StringBuilder xlWideStringBuffer = new StringBuilder();

    private final XSSFBCellHeader cellBuffer = new XSSFBCellHeader();
    public XSSFBSheetHandler(InputStream is,
                             XSSFBStylesTable styles,
                             XSSFBCommentsTable comments,
                             SharedStrings strings,
                             XSSFSheetXMLHandler.SheetContentsHandler sheetContentsHandler,
                             DataFormatter dataFormatter,
                             boolean formulasNotResults) {
        super(is);
        this.styles = styles;
        this.comments = comments;
        this.stringsTable = strings;
        this.handler = sheetContentsHandler;
        this.dataFormatter = dataFormatter;
        this.formulasNotResults = formulasNotResults;
    }

    @Override
    public void handleRecord(int id, byte[] data) throws XSSFBParseException {
        XSSFBRecordType type = XSSFBRecordType.lookup(id);

        switch(type) {
            case BrtRowHdr:
                int rw = XSSFBUtils.castToInt(LittleEndian.getUInt(data, 0));
                if (rw > 0x00100000) {//could make sure this is larger than currentRow, according to spec?
                    throw new XSSFBParseException("Row number beyond allowable range: "+rw);
                }
                currentRow = rw;
                checkMissedComments(currentRow);
                startRow(currentRow);
                break;
            case BrtCellIsst:
                handleBrtCellIsst(data);
                break;
            case BrtCellSt: //TODO: needs test
                handleCellSt(data);
                break;
            case BrtCellRk:
                handleCellRk(data);
                break;
            case BrtCellReal:
                handleCellReal(data);
                break;
            case BrtCellBool:
                handleBoolean(data);
                break;
            case BrtCellError:
                handleCellError(data);
                break;
            case BrtCellBlank:
                beforeCellValue(data);//read cell info and check for missing comments
                break;
            case BrtFmlaString:
                handleFmlaString(data);
                break;
            case BrtFmlaNum:
                handleFmlaNum(data);
                break;
            case BrtFmlaError:
                handleFmlaError(data);
                break;
                //TODO: All the PCDI and PCDIA
            case BrtEndSheetData:
                checkMissedComments(CHECK_ALL_ROWS);
                endRow(lastStartedRow);
                break;
            case BrtBeginHeaderFooter:
                handleHeaderFooter(data);
                break;
        }
    }


    private void beforeCellValue(byte[] data) {
        XSSFBCellHeader.parse(data, 0, currentRow, cellBuffer);
        checkMissedComments(currentRow, cellBuffer.getColNum());
    }

    private void handleCellValue(String formattedValue) {
        CellAddress cellAddress = new CellAddress(currentRow, cellBuffer.getColNum());
        XSSFBComment comment = null;
        if (comments != null) {
            comment = comments.get(cellAddress);
        }
        handler.cell(cellAddress.formatAsString(), formattedValue, comment);
    }

    private void handleFmlaNum(byte[] data) {
        beforeCellValue(data);
        //xNum
        double val = LittleEndian.getDouble(data, XSSFBCellHeader.length);
        handleCellValue(formatVal(val, cellBuffer.getStyleIdx()));
    }

    private void handleCellSt(byte[] data) {
        beforeCellValue(data);
        xlWideStringBuffer.setLength(0);
        XSSFBUtils.readXLWideString(data, XSSFBCellHeader.length, xlWideStringBuffer);
        handleCellValue(xlWideStringBuffer.toString());
    }

    private void handleFmlaString(byte[] data) {
        beforeCellValue(data);
        xlWideStringBuffer.setLength(0);
        XSSFBUtils.readXLWideString(data, XSSFBCellHeader.length, xlWideStringBuffer);
        handleCellValue(xlWideStringBuffer.toString());
    }

    private void handleCellError(byte[] data) {
        beforeCellValue(data);
        //TODO, read byte to figure out the type of error
        handleCellValue("ERROR");
    }

    private void handleFmlaError(byte[] data) {
        beforeCellValue(data);
        //TODO, read byte to figure out the type of error
        handleCellValue("ERROR");
    }

    private void handleBoolean(byte[] data) {
        beforeCellValue(data);
        String formattedVal = (data[XSSFBCellHeader.length] == 1) ? "TRUE" : "FALSE";
        handleCellValue(formattedVal);
    }

    private void handleCellReal(byte[] data) {
        beforeCellValue(data);
        //xNum
        double val = LittleEndian.getDouble(data, XSSFBCellHeader.length);
        handleCellValue(formatVal(val, cellBuffer.getStyleIdx()));
    }

    private void handleCellRk(byte[] data) {
        beforeCellValue(data);
        double val = rkNumber(data, XSSFBCellHeader.length);
        handleCellValue(formatVal(val, cellBuffer.getStyleIdx()));
    }

    private String formatVal(double val, int styleIdx) {
        String formatString = styles.getNumberFormatString(styleIdx);
        short styleIndex = styles.getNumberFormatIndex(styleIdx);
        //for now, if formatString is null, silently punt
        //and use "General".  Not the best behavior,
        //but we're doing it now in the streaming and non-streaming
        //extractors for xlsx.  See BUG-61053
        if (formatString == null) {
            formatString = BuiltinFormats.getBuiltinFormat(0);
            styleIndex = 0;
        }
        return dataFormatter.formatRawCellContents(val, styleIndex, formatString);
    }

    private void handleBrtCellIsst(byte[] data) {
        beforeCellValue(data);
        int idx = XSSFBUtils.castToInt(LittleEndian.getUInt(data, XSSFBCellHeader.length));
        RichTextString rtss = stringsTable.getItemAt(idx);
        handleCellValue(rtss.getString());
    }


    private void handleHeaderFooter(byte[] data) {
        XSSFBHeaderFooters headerFooter = XSSFBHeaderFooters.parse(data);
        outputHeaderFooter(headerFooter.getHeader());
        outputHeaderFooter(headerFooter.getFooter());
        outputHeaderFooter(headerFooter.getHeaderEven());
        outputHeaderFooter(headerFooter.getFooterEven());
        outputHeaderFooter(headerFooter.getHeaderFirst());
        outputHeaderFooter(headerFooter.getFooterFirst());
    }

    private void outputHeaderFooter(XSSFBHeaderFooter headerFooter) {
        String text = headerFooter.getString();
        if (text != null && text.trim().length() > 0) {
            handler.headerFooter(text, headerFooter.isHeader(), headerFooter.getHeaderFooterTypeLabel());
        }
    }


    //at start of next cell or end of row, return the cellAddress if it equals currentRow and col
    private void checkMissedComments(int currentRow, int colNum) {
        if (comments == null) {
            return;
        }
        Queue<CellAddress> queue = comments.getAddresses();
        while (queue.size() > 0) {
            CellAddress cellAddress = queue.peek();
            if (cellAddress.getRow() == currentRow && cellAddress.getColumn() < colNum) {
                cellAddress = queue.remove();
                dumpEmptyCellComment(cellAddress, comments.get(cellAddress));
            } else if (cellAddress.getRow() == currentRow && cellAddress.getColumn() == colNum) {
                queue.remove();
                return;
            } else if (cellAddress.getRow() == currentRow && cellAddress.getColumn() > colNum) {
                return;
            } else if (cellAddress.getRow() > currentRow) {
                return;
            }
        }
    }

    //check for anything from rows before
    private void checkMissedComments(int currentRow) {
        if (comments == null) {
            return;
        }
        Queue<CellAddress> queue = comments.getAddresses();
        int lastInterpolatedRow = -1;
        while (queue.size() > 0) {
            CellAddress cellAddress = queue.peek();
            if (currentRow == CHECK_ALL_ROWS || cellAddress.getRow() < currentRow) {
                cellAddress = queue.remove();
                if (cellAddress.getRow() != lastInterpolatedRow) {
                    startRow(cellAddress.getRow());
                }
                dumpEmptyCellComment(cellAddress, comments.get(cellAddress));
                lastInterpolatedRow = cellAddress.getRow();
            } else {
                break;
            }
        }

    }

    private void startRow(int row) {
        if (row == lastStartedRow) {
            return;
        }

        if (lastStartedRow != lastEndedRow) {
            endRow(lastStartedRow);
        }
        handler.startRow(row);
        lastStartedRow = row;
    }

    private void endRow(int row) {
        if (lastEndedRow == row) {
            return;
        }
        handler.endRow(row);
        lastEndedRow = row;
    }

    private void dumpEmptyCellComment(CellAddress cellAddress, XSSFBComment comment) {
        handler.cell(cellAddress.formatAsString(), null, comment);
    }

    private double rkNumber(byte[] data, int offset) {
        //see 2.5.122
        byte b0 = data[offset];
        boolean numDivBy100 = ((b0 & 1) == 1); // else as is
        boolean floatingPoint = ((b0 >> 1 & 1) == 0); // else signed integer

        //unset highest 2 bits
        b0 &= ~1;
        b0 &= ~(1<<1);

        rkBuffer[4] = b0;
        System.arraycopy(data, offset + 1, rkBuffer, 5, 3);
        double d = 0.0;
        if (floatingPoint) {
            d = LittleEndian.getDouble(rkBuffer);
        } else {
            int rawInt = LittleEndian.getInt(rkBuffer, 4);
            d = rawInt >> 2;//divide by 4/shift bits coz 30 bit int, not 32
        }
        d = (numDivBy100) ? d/100 : d;
        return d;
    }

    /**
     * You need to implement this to handle the results
     *  of the sheet parsing.
     */
    public interface SheetContentsHandler extends XSSFSheetXMLHandler.SheetContentsHandler {
        /**
         * A cell, with the given formatted value (may be null),
         * a url (may be null), a toolTip (may be null)
         *  and possibly a comment (may be null), was encountered */
        void hyperlinkCell(String cellReference, String formattedValue, String url, String toolTip, XSSFComment comment);
    }
}
