/*******************************************************************************
 * 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
 * ******************************************************************************
 * Jan Källman                      Added                       2012-03-04
 *******************************************************************************/

using System.Collections.Generic;
using System.Linq;
using OfficeOpenXml.FormulaParsing.Exceptions;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;

namespace OfficeOpenXml.FormulaParsing;

internal static class DependencyChainFactory {
  internal static DependencyChain Create(ExcelWorkbook wb, ExcelCalculationOption options) {
    var depChain = new DependencyChain();
    foreach (var ws in wb.Worksheets) {
      if (!(ws is ExcelChartsheet)) {
        GetChain(depChain, wb.FormulaParser.Lexer, ws.Cells, options);
        GetWorksheetNames(ws, depChain, options);
      }
    }
    foreach (var name in wb.Names) {
      if (name.NameValue == null) {
        GetChain(depChain, wb.FormulaParser.Lexer, name, options);
      }
    }
    return depChain;
  }

  internal static DependencyChain Create(ExcelWorksheet ws, ExcelCalculationOption options) {
    ws.CheckSheetType();
    var depChain = new DependencyChain();

    GetChain(depChain, ws.Workbook.FormulaParser.Lexer, ws.Cells, options);

    GetWorksheetNames(ws, depChain, options);

    return depChain;
  }

  internal static DependencyChain Create(
      ExcelWorksheet ws,
      string formula,
      ExcelCalculationOption options) {
    ws.CheckSheetType();
    var depChain = new DependencyChain();

    GetChain(depChain, ws.Workbook.FormulaParser.Lexer, ws, formula, options);

    return depChain;
  }

  private static void GetWorksheetNames(
      ExcelWorksheet ws,
      DependencyChain depChain,
      ExcelCalculationOption options) {
    foreach (var name in ws.Names) {
      if (!string.IsNullOrEmpty(name.NameFormula)) {
        GetChain(depChain, ws.Workbook.FormulaParser.Lexer, name, options);
      }
    }
  }

  internal static DependencyChain Create(ExcelRangeBase range, ExcelCalculationOption options) {
    var depChain = new DependencyChain();

    GetChain(depChain, range.Worksheet.Workbook.FormulaParser.Lexer, range, options);

    return depChain;
  }

  private static void GetChain(
      DependencyChain depChain,
      ILexer lexer,
      ExcelNamedRange name,
      ExcelCalculationOption options) {
    var ws = name.Worksheet;
    var id = ExcelCellBase.GetCellId(ws == null ? 0 : ws.SheetID, name.Index, 0);
    if (!depChain.index.ContainsKey(id)) {
      var f = new FormulaCell {
        SheetID = ws == null ? 0 : ws.SheetID,
        Row = name.Index,
        Column = 0,
        Formula = name.NameFormula,
      };
      if (!string.IsNullOrEmpty(f.Formula)) {
        f.Tokens = lexer.Tokenize(f.Formula, (ws == null ? null : ws.Name)).ToList();
        if (ws == null) {
          name._workbook._formulaTokens.SetValue(name.Index, 0, f.Tokens);
        } else {
          ws._formulaTokens.SetValue(name.Index, 0, f.Tokens);
        }
        depChain.Add(f);
        FollowChain(depChain, lexer, name._workbook, ws, f, options);
      }
    }
  }

  private static void GetChain(
      DependencyChain depChain,
      ILexer lexer,
      ExcelWorksheet ws,
      string formula,
      ExcelCalculationOption options) {
    var f = new FormulaCell {
      SheetID = ws.SheetID,
      Row = -1,
      Column = -1,
    };
    f.Formula = formula;
    if (!string.IsNullOrEmpty(f.Formula)) {
      f.Tokens = lexer.Tokenize(f.Formula, ws.Name).ToList();
      depChain.Add(f);
      FollowChain(depChain, lexer, ws.Workbook, ws, f, options);
    }
  }

  private static void GetChain(
      DependencyChain depChain,
      ILexer lexer,
      ExcelRangeBase range,
      ExcelCalculationOption options) {
    var ws = range.Worksheet;
    var fs = new CellsStoreEnumerator<object>(
        ws._formulas,
        range.Start.Row,
        range.Start.Column,
        range.End.Row,
        range.End.Column);
    while (fs.Next()) {
      if (fs.Value == null || fs.Value.ToString().Trim() == "") {
        continue;
      }
      var id = ExcelCellBase.GetCellId(ws.SheetID, fs.Row, fs.Column);
      if (!depChain.index.ContainsKey(id)) {
        var f = new FormulaCell {
          SheetID = ws.SheetID,
          Row = fs.Row,
          Column = fs.Column,
        };
        if (fs.Value is int) {
          f.Formula = ws._sharedFormulas[(int)fs.Value].GetFormula(fs.Row, fs.Column, ws.Name);
        } else {
          f.Formula = fs.Value.ToString();
        }
        if (!string.IsNullOrEmpty(f.Formula)) {
          f.Tokens = lexer.Tokenize(f.Formula, range.Worksheet.Name).ToList();
          ws._formulaTokens.SetValue(fs.Row, fs.Column, f.Tokens);
          depChain.Add(f);
          FollowChain(depChain, lexer, ws.Workbook, ws, f, options);
        }
      }
    }
  }

  /// <summary>
  /// This method follows the calculation chain to get the order of the calculation
  /// Goto (!) is used internally to prevent stackoverflow on extremly larget dependency trees (that is, many recursive formulas).
  /// </summary>
  /// <param name="depChain">The dependency chain object</param>
  /// <param name="lexer">The formula tokenizer</param>
  /// <param name="wb">The workbook where the formula comes from</param>
  /// <param name="ws">The worksheet where the formula comes from</param>
  /// <param name="f">The cell function object</param>
  /// <param name="options">Calcultaiton options</param>
  private static void FollowChain(
      DependencyChain depChain,
      ILexer lexer,
      ExcelWorkbook wb,
      ExcelWorksheet ws,
      FormulaCell f,
      ExcelCalculationOption options) {
    Stack<FormulaCell> stack = new Stack<FormulaCell>();
    iterateToken:
    while (f.tokenIx < f.Tokens.Count) {
      var t = f.Tokens[f.tokenIx];
      if (t.TokenType == TokenType.ExcelAddress) {
        var adr = new ExcelFormulaAddress(t.Value);
        if (adr.Table != null) {
          adr.SetRcFromTable(ws._package, new(f.Row, f.Column, f.Row, f.Column));
        }

        if (adr.WorkSheet == null
            && adr.Collide(new(f.Row, f.Column, f.Row, f.Column))
                != ExcelAddressBase.eAddressCollition.No) {
          throw (new CircularReferenceException(
                  string.Format(
                      "Circular Reference in cell {0}",
                      ExcelCellBase.GetAddress(f.Row, f.Column))));
        }

        if (adr._fromRow > 0 && adr._fromCol > 0) {
          if (string.IsNullOrEmpty(adr.WorkSheet)) {
            if (f.ws == null) {
              f.ws = ws;
            } else if (f.ws.SheetID != f.SheetID) {
              f.ws = wb.Worksheets.GetBySheetId(f.SheetID);
            }
          } else {
            f.ws = wb.Worksheets[adr.WorkSheet];
          }

          if (f.ws != null) {
            f.iterator = new(
                f.ws._formulas,
                adr.Start.Row,
                adr.Start.Column,
                adr.End.Row,
                adr.End.Column);
            goto iterateCells;
          }
        }
      } else if (t.TokenType == TokenType.NameValue) {
        string adrWb,
            adrWs,
            adrName;
        ExcelNamedRange name;
        ExcelAddressBase.SplitAddress(
            t.Value,
            out adrWb,
            out adrWs,
            out adrName,
            f.ws == null ? "" : f.ws.Name);
        if (!string.IsNullOrEmpty(adrWs)) {
          if (f.ws == null) {
            f.ws = wb.Worksheets[adrWs];
          }
          if (f.ws.Names.ContainsKey(t.Value)) {
            name = f.ws.Names[adrName];
          } else if (wb.Names.ContainsKey(adrName)) {
            name = wb.Names[adrName];
          } else {
            name = null;
          }
          if (name != null) {
            f.ws = name.Worksheet;
          }
        } else if (wb.Names.ContainsKey(adrName)) {
          name = wb.Names[t.Value];
          if (string.IsNullOrEmpty(adrWs)) {
            f.ws = name.Worksheet;
          }
        } else {
          name = null;
        }

        if (name != null) {
          if (string.IsNullOrEmpty(name.NameFormula)) {
            if (name.NameValue == null) {
              f.iterator = new(
                  f.ws._formulas,
                  name.Start.Row,
                  name.Start.Column,
                  name.End.Row,
                  name.End.Column);
              goto iterateCells;
            }
          } else {
            var id = ExcelCellBase.GetCellId(name.LocalSheetId, name.Index, 0);

            if (!depChain.index.ContainsKey(id)) {
              var rf = new FormulaCell {
                SheetID = name.LocalSheetId,
                Row = name.Index,
                Column = 0,
              };
              rf.Formula = name.NameFormula;
              rf.Tokens =
                  name.LocalSheetId == -1
                      ? lexer.Tokenize(rf.Formula).ToList()
                      : lexer
                          .Tokenize(rf.Formula, wb.Worksheets.GetBySheetId(name.LocalSheetId).Name)
                          .ToList();

              depChain.Add(rf);
              stack.Push(f);
              f = rf;
              goto iterateToken;
            }
            if (stack.Count > 0) {
              //Check for circular references
              foreach (var par in stack) {
                if (ExcelCellBase.GetCellId(par.SheetID, par.Row, par.Column) == id) {
                  throw (new CircularReferenceException(
                          string.Format("Circular Reference in name {0}", name.Name)));
                }
              }
            }
          }
        }
      }
      f.tokenIx++;
    }
    depChain.CalcOrder.Add(f.Index);
    if (stack.Count > 0) {
      f = stack.Pop();
      goto iterateCells;
    }
    return;
    iterateCells:

    while (f.iterator != null && f.iterator.Next()) {
      var v = f.iterator.Value;
      if (v == null || v.ToString().Trim() == "") {
        continue;
      }
      var id = ExcelCellBase.GetCellId(f.ws.SheetID, f.iterator.Row, f.iterator.Column);
      if (!depChain.index.ContainsKey(id)) {
        var rf = new FormulaCell {
          SheetID = f.ws.SheetID,
          Row = f.iterator.Row,
          Column = f.iterator.Column,
        };
        if (f.iterator.Value is int) {
          rf.Formula = f.ws._sharedFormulas[(int)v]
              .GetFormula(f.iterator.Row, f.iterator.Column, ws.Name);
        } else {
          rf.Formula = v.ToString();
        }
        rf.ws = f.ws;
        rf.Tokens = lexer.Tokenize(rf.Formula, f.ws.Name).ToList();
        ws._formulaTokens.SetValue(rf.Row, rf.Column, rf.Tokens);
        depChain.Add(rf);
        stack.Push(f);
        f = rf;
        goto iterateToken;
      }
      if (stack.Count > 0) {
        //Check for circular references
        foreach (var par in stack) {
          if (ExcelCellBase.GetCellId(par.ws.SheetID, par.iterator.Row, par.iterator.Column)
              == id) {
            if (options.AllowCirculareReferences == false) {
              throw (new CircularReferenceException(
                      string.Format(
                          "Circular Reference in cell {0}!{1}",
                          par.ws.Name,
                          ExcelCellBase.GetAddress(f.Row, f.Column))));
            }
            f = stack.Pop();
            goto iterateCells;
          }
        }
      }
    }
    f.tokenIx++;
    goto iterateToken;
  }
}
