/*******************************************************************************
 * You may amend and distribute as you like, but don't remove this header!
 *
 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
 * See http://www.codeplex.com/EPPlus for details.
 *
 * Copyright (C) 2011  Jan Källman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
 *
 * All code and executables are provided "as is" with no warranty either express or implied.
 * The author accepts no liability for any damage or loss of business that this product may cause.
 *
 * Code change notes:
 *
 * Author							Change						Date
 * ******************************************************************************
 * Mats Alm   		                Added       		        2013-03-01 (Prior file history on https://github.com/swmal/ExcelFormulaParser)
 *******************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;

namespace AppsheetEpplus;

public class FormulaParser {
  private readonly ParsingContext _parsingContext;
  private readonly ExcelDataProvider _excelDataProvider;

  public FormulaParser(ExcelDataProvider excelDataProvider)
      : this(excelDataProvider, ParsingContext.Create()) {}

  public FormulaParser(ExcelDataProvider excelDataProvider, ParsingContext parsingContext) {
    parsingContext.Parser = this;
    parsingContext.ExcelDataProvider = excelDataProvider;
    parsingContext.NameValueProvider = new EpplusNameValueProvider(excelDataProvider);
    parsingContext.RangeAddressFactory = new(excelDataProvider);
    _parsingContext = parsingContext;
    _excelDataProvider = excelDataProvider;
    Configure(configuration => {
      configuration
          .SetLexer(
              new Lexer(
                  _parsingContext.Configuration.FunctionRepository,
                  _parsingContext.NameValueProvider))
          .SetGraphBuilder(new ExpressionGraphBuilder(excelDataProvider, _parsingContext))
          .SetExpresionCompiler(new ExpressionCompiler())
          .FunctionRepository.LoadModule(new BuiltInFunctions());
    });
  }

  public void Configure(Action<ParsingConfiguration> configMethod) {
    configMethod.Invoke(_parsingContext.Configuration);
    _lexer = _parsingContext.Configuration.Lexer ?? _lexer;
    _graphBuilder = _parsingContext.Configuration.GraphBuilder ?? _graphBuilder;
    _compiler = _parsingContext.Configuration.ExpressionCompiler ?? _compiler;
  }

  private ILexer _lexer;
  private IExpressionGraphBuilder _graphBuilder;
  private IExpressionCompiler _compiler;

  public ILexer Lexer => _lexer;

  public IEnumerable<string> FunctionNames =>
    _parsingContext.Configuration.FunctionRepository.FunctionNames;

  internal virtual object Parse(string formula, RangeAddress rangeAddress) {
    using (var scope = _parsingContext.Scopes.NewScope(rangeAddress)) {
      var tokens = _lexer.Tokenize(formula);
      var graph = _graphBuilder.Build(tokens);
      if (graph.Expressions.Count() == 0) {
        return null;
      }
      return _compiler.Compile(graph.Expressions).Result;
    }
  }

  internal virtual object Parse(IEnumerable<Token> tokens, string worksheet, string address) {
    var rangeAddress = _parsingContext.RangeAddressFactory.Create(address);
    using (var scope = _parsingContext.Scopes.NewScope(rangeAddress)) {
      var graph = _graphBuilder.Build(tokens);
      if (graph.Expressions.Count() == 0) {
        return null;
      }
      return _compiler.Compile(graph.Expressions).Result;
    }
  }

  internal virtual object ParseCell(
      IEnumerable<Token> tokens,
      string worksheet,
      int row,
      int column) {
    var rangeAddress = _parsingContext.RangeAddressFactory.Create(worksheet, column, row);
    using (var scope = _parsingContext.Scopes.NewScope(rangeAddress)) {
      //    _parsingContext.Dependencies.AddFormulaScope(scope);
      var graph = _graphBuilder.Build(tokens);
      if (graph.Expressions.Count() == 0) {
        return 0d;
      }
      try {
        var compileResult = _compiler.Compile(graph.Expressions);
        // quick solution for the fact that an excelrange can be returned.
        var rangeInfo = compileResult.Result as ExcelDataProvider.IRangeInfo;
        if (rangeInfo == null) {
          return compileResult.Result ?? 0d;
        }
        if (rangeInfo.IsEmpty) {
          return 0d;
        }
        if (!rangeInfo.IsMulti) {
          return rangeInfo.First().Value ?? 0d;
        }
        // ok to return multicell if it is a workbook scoped name.
        if (string.IsNullOrEmpty(worksheet)) {
          return rangeInfo;
        }
        if (_parsingContext.Debug) {
          var msg = string.Format(
              "A range with multiple cell was returned at row {0}, column {1}",
              row,
              column);
          _parsingContext.Configuration.Logger.Log(_parsingContext, msg);
        }
        return ExcelErrorValue.Create(eErrorType.Value);
      } catch (ExcelErrorValueException ex) {
        if (_parsingContext.Debug) {
          _parsingContext.Configuration.Logger.Log(_parsingContext, ex);
        }
        return ex.ErrorValue;
      }
    }
  }

  public virtual object Parse(string formula, string address) {
    return Parse(formula, _parsingContext.RangeAddressFactory.Create(address));
  }

  public virtual object Parse(string formula) {
    return Parse(formula, RangeAddress.Empty);
  }

  public virtual object ParseAt(string address) {
    Require.That(address).Named("address").IsNotNullOrEmpty();
    var rangeAddress = _parsingContext.RangeAddressFactory.Create(address);
    return ParseAt(rangeAddress.Worksheet, rangeAddress.FromRow, rangeAddress.FromCol);
  }

  public virtual object ParseAt(string worksheetName, int row, int col) {
    var f = _excelDataProvider.GetRangeFormula(worksheetName, row, col);
    if (string.IsNullOrEmpty(f)) {
      return _excelDataProvider.GetRangeValue(worksheetName, row, col);
    }
    return Parse(f, _parsingContext.RangeAddressFactory.Create(worksheetName, col, row));
    //var dataItem = _excelDataProvider.GetRangeValues(address).FirstOrDefault();
    //if (dataItem == null /*|| (dataItem.Value == null && dataItem.Formula == null)*/) return null;
    //if (!string.IsNullOrEmpty(dataItem.Formula))
    //{
    //    return Parse(dataItem.Formula, _parsingContext.RangeAddressFactory.Create(address));
    //}
    //return Parse(dataItem.Value.ToString(), _parsingContext.RangeAddressFactory.Create(address));
  }

  internal void InitNewCalc() {
    if (_excelDataProvider != null) {
      _excelDataProvider.Reset();
    }
  }

  // Praveen's Formula Parser
  public ExpressionGraph ParseToGraph(string formula) {
    using (var scope = _parsingContext.Scopes.NewScope(RangeAddress.Empty)) {
      var tokens = _lexer.Tokenize(formula);
      var graph = _graphBuilder.Build(tokens);
      return graph;
    }
  }
}
