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

import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.model.InternalWorkbook;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationName;
import org.apache.poi.ss.formula.EvaluationSheet;
import org.apache.poi.ss.formula.EvaluationWorkbook;
import org.apache.poi.ss.formula.FormulaParseException;
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.SheetIdentifier;
import org.apache.poi.ss.formula.SheetRangeIdentifier;
import org.apache.poi.ss.formula.ptg.Area3DPtg;
import org.apache.poi.ss.formula.ptg.NamePtg;
import org.apache.poi.ss.formula.ptg.NameXPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.ptg.Ref3DPtg;
import org.apache.poi.ss.formula.udf.UDFFinder;
import org.apache.poi.ss.usermodel.Table;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;

/**
 * Internal POI use only
 */
@Internal
public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook, FormulaParsingWorkbook {
    private static POILogger logger = POILogFactory.getLogger(HSSFEvaluationWorkbook.class);
    private final HSSFWorkbook _uBook;
    private final InternalWorkbook _iBook;

    public static HSSFEvaluationWorkbook create(HSSFWorkbook book) {
        if (book == null) {
            return null;
        }
        return new HSSFEvaluationWorkbook(book);
    }

    private HSSFEvaluationWorkbook(HSSFWorkbook book) {
        _uBook = book;
        _iBook = book.getWorkbook();
    }

    /* (non-JavaDoc), inherit JavaDoc from EvaluationWorkbook
     * @since POI 3.15 beta 3
     */
    @Override
    public void clearAllCachedResultValues() {
        // nothing to do
    }
    
    @Override
    public HSSFName createName() {
        return _uBook.createName();
    }

    @Override
    public int getExternalSheetIndex(String sheetName) {
        int sheetIndex = _uBook.getSheetIndex(sheetName);
        return _iBook.checkExternSheet(sheetIndex);
    }
    @Override
    public int getExternalSheetIndex(String workbookName, String sheetName) {
        return _iBook.getExternalSheetIndex(workbookName, sheetName);
    }
    
    @Override
    public Ptg get3DReferencePtg(CellReference cr, SheetIdentifier sheet) {
        int extIx = getSheetExtIx(sheet);
        return new Ref3DPtg(cr, extIx);
    }
    @Override
    public Ptg get3DReferencePtg(AreaReference areaRef, SheetIdentifier sheet) {
        int extIx = getSheetExtIx(sheet);
        return new Area3DPtg(areaRef, extIx);
    }
    /**
     * Return an external name (named range, function, user-defined function) Ptg
     */
    @Override
    public NameXPtg getNameXPtg(String name, SheetIdentifier sheet) {
        int sheetRefIndex = getSheetExtIx(sheet);
        return _iBook.getNameXPtg(name, sheetRefIndex, _uBook.getUDFFinder());
    }

    /**
     * Lookup a named range by its name.
     *
     * @param name the name to search
     * @param sheetIndex  the 0-based index of the sheet this formula belongs to.
     * The sheet index is required to resolve sheet-level names. <code>-1</code> means workbook-global names
     */
    public EvaluationName getName(String name, int sheetIndex) {
        for(int i=0; i < _iBook.getNumNames(); i++) {
            NameRecord nr = _iBook.getNameRecord(i);
            if (nr.getSheetNumber() == sheetIndex+1 && name.equalsIgnoreCase(nr.getNameText())) {
                return new Name(nr, i);
            }
        }
        return sheetIndex == -1 ? null : getName(name, -1);
    }

    @Override
    public int getSheetIndex(EvaluationSheet evalSheet) {
        HSSFSheet sheet = ((HSSFEvaluationSheet)evalSheet).getHSSFSheet();
        return _uBook.getSheetIndex(sheet);
    }
    @Override
    public int getSheetIndex(String sheetName) {
        return _uBook.getSheetIndex(sheetName);
    }

    @Override
    public String getSheetName(int sheetIndex) {
        return _uBook.getSheetName(sheetIndex);
    }

    @Override
    public EvaluationSheet getSheet(int sheetIndex) {
        // TODO Cache these evaluation sheets so they aren't re-generated on every getSheet call
        return new HSSFEvaluationSheet(_uBook.getSheetAt(sheetIndex));
    }
    @Override
    public int convertFromExternSheetIndex(int externSheetIndex) {
        // TODO Update this to expose first and last sheet indexes
        return _iBook.getFirstSheetIndexFromExternSheetIndex(externSheetIndex);
    }

    @Override
    public ExternalSheet getExternalSheet(int externSheetIndex) {
        ExternalSheet sheet = _iBook.getExternalSheet(externSheetIndex);
        if (sheet == null) {
            // Try to treat it as a local sheet
            int localSheetIndex = convertFromExternSheetIndex(externSheetIndex);
            if (localSheetIndex == -1) {
                // The sheet referenced can't be found, sorry
                return null;
            }
            if (localSheetIndex == -2) {
                // Not actually sheet based at all - is workbook scoped
                return null;
            }
            
            // Look up the local sheet
            String sheetName = getSheetName(localSheetIndex);
            
            // Is it a single local sheet, or a range?
            int lastLocalSheetIndex = _iBook.getLastSheetIndexFromExternSheetIndex(externSheetIndex);
            if (lastLocalSheetIndex == localSheetIndex) {
                sheet = new ExternalSheet(null, sheetName);
            } else {
                String lastSheetName = getSheetName(lastLocalSheetIndex);
                sheet = new ExternalSheetRange(null, sheetName, lastSheetName);
            }
        }
        return sheet;
    }

    /**
     * @throws IllegalStateException: XSSF-style external references are not supported for HSSF
     */
    @Override
    public ExternalSheet getExternalSheet(String firstSheetName, String lastSheetName, int externalWorkbookNumber) {
        throw new IllegalStateException("XSSF-style external references are not supported for HSSF");
    }

    @Override
    public ExternalName getExternalName(int externSheetIndex, int externNameIndex) {
        return _iBook.getExternalName(externSheetIndex, externNameIndex);
    }

    /**
     * @throws IllegalStateException: XSSF-style external names are not supported for HSSF
     */
    @Override
    public ExternalName getExternalName(String nameName, String sheetName, int externalWorkbookNumber) {
        throw new IllegalStateException("XSSF-style external names are not supported for HSSF");
    }

    @Override
    public String resolveNameXText(NameXPtg n) {
        return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());
    }

    @Override
    public String getSheetFirstNameByExternSheet(int externSheetIndex) {
        return _iBook.findSheetFirstNameFromExternSheet(externSheetIndex);
    }
    @Override
    public String getSheetLastNameByExternSheet(int externSheetIndex) {
        return _iBook.findSheetLastNameFromExternSheet(externSheetIndex);
    }
    @Override
    public String getNameText(NamePtg namePtg) {
        return _iBook.getNameRecord(namePtg.getIndex()).getNameText();
    }
    @Override
    public EvaluationName getName(NamePtg namePtg) {
        int ix = namePtg.getIndex();
        return new Name(_iBook.getNameRecord(ix), ix);
    }

    @Override
    @SuppressWarnings("unused")
    public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
        HSSFCell cell = ((HSSFEvaluationCell)evalCell).getHSSFCell();
        if (false) {
            // re-parsing the formula text also works, but is a waste of time
            // It is useful from time to time to run all unit tests with this code
            // to make sure that all formulas POI can evaluate can also be parsed.
            try {
                return HSSFFormulaParser.parse(cell.getCellFormula(), _uBook, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet()));
            } catch (FormulaParseException e) {
                // Note - as of Bugzilla 48036 (svn r828244, r828247) POI is capable of evaluating
                // IntesectionPtg.  However it is still not capable of parsing it.
                // So FormulaEvalTestData.xls now contains a few formulas that produce errors here.
                logger.log( POILogger.ERROR, e.getMessage());
            }
        }
        FormulaRecordAggregate fra = (FormulaRecordAggregate) cell.getCellValueRecord();
        return fra.getFormulaTokens();
    }

    @Override
    public UDFFinder getUDFFinder(){
        return _uBook.getUDFFinder();
    }

    private static final class Name implements EvaluationName {
        private final NameRecord _nameRecord;
        private final int _index;

        public Name(NameRecord nameRecord, int index) {
            _nameRecord = nameRecord;
            _index = index;
        }
        public Ptg[] getNameDefinition() {
            return _nameRecord.getNameDefinition();
        }
        public String getNameText() {
            return _nameRecord.getNameText();
        }
        public boolean hasFormula() {
            return _nameRecord.hasFormula();
        }
        public boolean isFunctionName() {
            return _nameRecord.isFunctionName();
        }
        public boolean isRange() {
            return _nameRecord.hasFormula(); // TODO - is this right?
        }
        public NamePtg createPtg() {
            return new NamePtg(_index);
        }
    }

    private int getSheetExtIx(SheetIdentifier sheetIden) {
        int extIx;
        if (sheetIden == null) {
            extIx = -1;
        } else {
            String workbookName = sheetIden.getBookName(); 
            String firstSheetName = sheetIden.getSheetIdentifier().getName();
            String lastSheetName = firstSheetName;
            
            if (sheetIden instanceof SheetRangeIdentifier) {
                lastSheetName = ((SheetRangeIdentifier)sheetIden).getLastSheetIdentifier().getName();
            }
            
            if (workbookName == null) {
                int firstSheetIndex = _uBook.getSheetIndex(firstSheetName);
                int lastSheetIndex = _uBook.getSheetIndex(lastSheetName);
                extIx = _iBook.checkExternSheet(firstSheetIndex, lastSheetIndex);
            } else {
                extIx = _iBook.getExternalSheetIndex(workbookName, firstSheetName, lastSheetName);
            }
        }
        return extIx;
    }

    @Override
    public SpreadsheetVersion getSpreadsheetVersion(){
        return SpreadsheetVersion.EXCEL97;
    }

    /**
      * @throws IllegalStateException: data tables are not supported in Excel 97-2003 format
      */
    @Override
    public Table getTable(String name) {
        throw new IllegalStateException("XSSF-style tables are not supported for HSSF");
    }
}
