/*******************************************************************************
 * 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;

namespace AppsheetEpplus;

public class Operator : IOperator {
  private const int _precedencePercent = 2;
  private const int _precedenceExp = 4;
  private const int _precedenceMultiplyDevide = 6;
  private const int _precedenceAddSubtract = 12;
  private const int _precedenceConcat = 15;
  private const int _precedenceComparison = 25;

  private Operator(
      Operators @operator,
      int precedence,
      Func<CompileResult, CompileResult, CompileResult> implementation) {
    _implementation = implementation;
    _precedence = precedence;
    _operator = @operator;
  }

  private readonly Func<CompileResult, CompileResult, CompileResult> _implementation;
  private readonly int _precedence;
  private readonly Operators _operator;

  int IOperator.Precedence => _precedence;

  Operators IOperator.Operator => _operator;

  public CompileResult Apply(CompileResult left, CompileResult right) {
    if (left.Result is ExcelErrorValue) {
      return new(left.Result, DataType.ExcelError);
      //throw(new ExcelErrorValueException((ExcelErrorValue)left.Result));
    }
    if (right.Result is ExcelErrorValue) {
      return new(right.Result, DataType.ExcelError);
      //throw(new ExcelErrorValueException((ExcelErrorValue)right.Result));
    }
    return _implementation(left, right);
  }

  public override string ToString() {
    return "Operator: " + _operator;
  }

  private static IOperator _plus;

  public static IOperator Plus {
    get {
      return _plus
          ?? (_plus = new Operator(
                  Operators.Plus,
                  _precedenceAddSubtract,
                  (l, r) => {
                    l = l == null || l.Result == null ? new(0, DataType.Integer) : l;
                    r = r == null || r.Result == null ? new(0, DataType.Integer) : r;
                    if (EitherIsError(l, r, out var errorVal)) {
                      return new(errorVal);
                    }
                    if (l.DataType == DataType.Integer && r.DataType == DataType.Integer) {
                      return new(l.ResultNumeric + r.ResultNumeric, DataType.Integer);
                    }
                    if ((l.IsNumeric
                                || l.IsNumericString
                                || l.Result is ExcelDataProvider.IRangeInfo)
                        && (r.IsNumeric
                                || r.IsNumericString
                                || r.Result is ExcelDataProvider.IRangeInfo)) {
                      return new(l.ResultNumeric + r.ResultNumeric, DataType.Decimal);
                    }
                    return new(eErrorType.Value);
                  }));
    }
  }

  private static IOperator _minus;

  public static IOperator Minus {
    get {
      return _minus
          ?? (_minus = new Operator(
                  Operators.Minus,
                  _precedenceAddSubtract,
                  (l, r) => {
                    l = l == null || l.Result == null ? new(0, DataType.Integer) : l;
                    r = r == null || r.Result == null ? new(0, DataType.Integer) : r;
                    if (l.DataType == DataType.Integer && r.DataType == DataType.Integer) {
                      return new(l.ResultNumeric - r.ResultNumeric, DataType.Integer);
                    }
                    if ((l.IsNumeric
                                || l.IsNumericString
                                || l.Result is ExcelDataProvider.IRangeInfo)
                        && (r.IsNumeric
                                || r.IsNumericString
                                || r.Result is ExcelDataProvider.IRangeInfo)) {
                      return new(l.ResultNumeric - r.ResultNumeric, DataType.Decimal);
                    }

                    return new(eErrorType.Value);
                  }));
    }
  }

  private static IOperator _multiply;

  public static IOperator Multiply {
    get {
      return _multiply
          ?? (_multiply = new Operator(
                  Operators.Multiply,
                  _precedenceMultiplyDevide,
                  (l, r) => {
                    l = l ?? new CompileResult(0, DataType.Integer);
                    r = r ?? new CompileResult(0, DataType.Integer);
                    if (l.DataType == DataType.Integer && r.DataType == DataType.Integer) {
                      return new(l.ResultNumeric * r.ResultNumeric, DataType.Integer);
                    }
                    if ((l.IsNumeric
                                || l.IsNumericString
                                || l.Result is ExcelDataProvider.IRangeInfo)
                        && (r.IsNumeric
                                || r.IsNumericString
                                || r.Result is ExcelDataProvider.IRangeInfo)) {
                      return new(l.ResultNumeric * r.ResultNumeric, DataType.Decimal);
                    }
                    return new(eErrorType.Value);
                  }));
    }
  }

  private static IOperator _divide;

  public static IOperator Divide {
    get {
      return _divide
          ?? (_divide = new Operator(
                  Operators.Divide,
                  _precedenceMultiplyDevide,
                  (l, r) => {
                    if (!(l.IsNumeric
                                || l.IsNumericString
                                || l.Result is ExcelDataProvider.IRangeInfo)
                        || !(r.IsNumeric
                                || r.IsNumericString
                                || r.Result is ExcelDataProvider.IRangeInfo)) {
                      return new(eErrorType.Value);
                    }
                    var left = l.ResultNumeric;
                    var right = r.ResultNumeric;
                    if (Math.Abs(right - 0d) < double.Epsilon) {
                      return new(eErrorType.Div0);
                    }
                    if ((l.IsNumeric
                                || l.IsNumericString
                                || l.Result is ExcelDataProvider.IRangeInfo)
                        && (r.IsNumeric
                                || r.IsNumericString
                                || r.Result is ExcelDataProvider.IRangeInfo)) {
                      return new(left / right, DataType.Decimal);
                    }
                    return new(eErrorType.Value);
                  }));
    }
  }

  public static IOperator Exp {
    get {
      return new Operator(
          Operators.Exponentiation,
          _precedenceExp,
          (l, r) => {
            if (l == null && r == null) {
              return new(eErrorType.Value);
            }
            l = l ?? new CompileResult(0, DataType.Integer);
            r = r ?? new CompileResult(0, DataType.Integer);
            if ((l.IsNumeric || l.Result is ExcelDataProvider.IRangeInfo)
                && (r.IsNumeric || r.Result is ExcelDataProvider.IRangeInfo)) {
              return new(Math.Pow(l.ResultNumeric, r.ResultNumeric), DataType.Decimal);
            }
            return new(0d, DataType.Decimal);
          });
    }
  }

  public static IOperator Concat {
    get {
      return new Operator(
          Operators.Concat,
          _precedenceConcat,
          (l, r) => {
            l = l ?? new CompileResult(string.Empty, DataType.String);
            r = r ?? new CompileResult(string.Empty, DataType.String);
            var lStr = l.Result != null ? l.ResultValue.ToString() : string.Empty;
            var rStr = r.Result != null ? r.ResultValue.ToString() : string.Empty;
            return new(string.Concat(lStr, rStr), DataType.String);
          });
    }
  }

  private static IOperator _greaterThan;

  public static IOperator GreaterThan {
    get {
      //return new Operator(Operators.GreaterThan, PrecedenceComparison, (l, r) => new CompileResult(Compare(l, r) > 0, DataType.Boolean));
      return _greaterThan
          ?? (_greaterThan = new Operator(
                  Operators.LessThanOrEqual,
                  _precedenceComparison,
                  (l, r) => Compare(l, r, compRes => compRes > 0)));
    }
  }

  private static IOperator _eq;

  public static IOperator Eq {
    get {
      //return new Operator(Operators.Equals, PrecedenceComparison, (l, r) => new CompileResult(Compare(l, r) == 0, DataType.Boolean));
      return _eq
          ?? (_eq = new Operator(
                  Operators.LessThanOrEqual,
                  _precedenceComparison,
                  (l, r) => Compare(l, r, compRes => compRes == 0)));
    }
  }

  private static IOperator _notEqualsTo;

  public static IOperator NotEqualsTo {
    get {
      //return new Operator(Operators.NotEqualTo, PrecedenceComparison, (l, r) => new CompileResult(Compare(l, r) != 0, DataType.Boolean));
      return _notEqualsTo
          ?? (_notEqualsTo = new Operator(
                  Operators.LessThanOrEqual,
                  _precedenceComparison,
                  (l, r) => Compare(l, r, compRes => compRes != 0)));
    }
  }

  private static IOperator _greaterThanOrEqual;

  public static IOperator GreaterThanOrEqual {
    get {
      //return new Operator(Operators.GreaterThanOrEqual, PrecedenceComparison, (l, r) => new CompileResult(Compare(l, r) >= 0, DataType.Boolean));
      return _greaterThanOrEqual
          ?? (_greaterThanOrEqual = new Operator(
                  Operators.LessThanOrEqual,
                  _precedenceComparison,
                  (l, r) => Compare(l, r, compRes => compRes >= 0)));
    }
  }

  private static IOperator _lessThan;

  public static IOperator LessThan {
    get {
      //return new Operator(Operators.LessThan, PrecedenceComparison, (l, r) => new CompileResult(Compare(l, r) < 0, DataType.Boolean));
      return _lessThan
          ?? (_lessThan = new Operator(
                  Operators.LessThanOrEqual,
                  _precedenceComparison,
                  (l, r) => Compare(l, r, compRes => compRes < 0)));
    }
  }

  public static IOperator LessThanOrEqual {
    get {
      //return new Operator(Operators.LessThanOrEqual, PrecedenceComparison, (l, r) => new CompileResult(Compare(l, r) <= 0, DataType.Boolean));
      return new Operator(
          Operators.LessThanOrEqual,
          _precedenceComparison,
          (l, r) => Compare(l, r, compRes => compRes <= 0));
    }
  }

  private static IOperator _percent;

  public static IOperator Percent {
    get {
      if (_percent == null) {
        _percent = new Operator(
            Operators.Percent,
            _precedencePercent,
            (l, r) => {
              l = l ?? new CompileResult(0, DataType.Integer);
              r = r ?? new CompileResult(0, DataType.Integer);
              if (l.DataType == DataType.Integer && r.DataType == DataType.Integer) {
                return new(l.ResultNumeric * r.ResultNumeric, DataType.Integer);
              }
              if ((l.IsNumeric || l.Result is ExcelDataProvider.IRangeInfo)
                  && (r.IsNumeric || r.Result is ExcelDataProvider.IRangeInfo)) {
                return new(l.ResultNumeric * r.ResultNumeric, DataType.Decimal);
              }
              return new(eErrorType.Value);
            });
      }
      return _percent;
    }
  }

  private static object GetObjFromOther(CompileResult obj, CompileResult other) {
    if (obj.Result == null) {
      if (other.DataType == DataType.String) {
        return string.Empty;
      }
      return 0d;
    }
    return obj.ResultValue;
  }

  private static CompileResult Compare(
      CompileResult l,
      CompileResult r,
      Func<int, bool> comparison) {
    if (EitherIsError(l, r, out var errorVal)) {
      return new(errorVal);
    }
    object left,
        right;
    left = GetObjFromOther(l, r);
    right = GetObjFromOther(r, l);
    if (ConvertUtil.IsNumeric(left) && ConvertUtil.IsNumeric(right)) {
      var lnum = ConvertUtil.GetValueDouble(left);
      var rnum = ConvertUtil.GetValueDouble(right);
      if (Math.Abs(lnum - rnum) < double.Epsilon) {
        return new(comparison(0), DataType.Boolean);
      }
      var comparisonResult = lnum.CompareTo(rnum);
      return new(comparison(comparisonResult), DataType.Boolean);
    } else {
      var comparisonResult = CompareString(left, right);
      return new(comparison(comparisonResult), DataType.Boolean);
    }
  }

  private static int CompareString(object l, object r) {
    var sl = (l ?? "").ToString();
    var sr = (r ?? "").ToString();
    return String.Compare(sl, sr, StringComparison.Ordinal);
  }

  private static bool EitherIsError(
      CompileResult l,
      CompileResult r,
      out ExcelErrorValue errorVal) {
    if (l.DataType == DataType.ExcelError) {
      errorVal = (ExcelErrorValue)l.Result;
      return true;
    }
    if (r.DataType == DataType.ExcelError) {
      errorVal = (ExcelErrorValue)r.Result;
      return true;
    }
    errorVal = null;
    return false;
  }
}
