/*******************************************************************************
 * 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		    Initial Release		         2009-10-01
 * Jan Källman		    License changed GPL-->LGPL 2011-12-27
 * Eyal Seagull       Add "CreateComplexNode"    2012-04-03
 * Eyal Seagull       Add "DeleteTopNode"        2012-04-13
 *******************************************************************************/

using System;
using System.Collections.Immutable;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;

namespace AppsheetEpplus;

/// <summary>
/// Help class containing XML functions.
/// Can be Inherited
/// </summary>
public abstract class XmlHelper {
  internal delegate int ChangedEventHandler(StyleBase sender, StyleChangeEventArgs e);

  internal XmlHelper(XmlNamespaceManager nameSpaceManager) {
    TopNode = null;
    NameSpaceManager = nameSpaceManager;
  }

  internal XmlHelper(XmlNamespaceManager nameSpaceManager, XmlNode topNode) {
    TopNode = topNode;
    NameSpaceManager = nameSpaceManager;
  }

  //internal bool ChangedFlag;
  internal XmlNamespaceManager NameSpaceManager { get; set; }

  internal XmlNode TopNode { get; set; }

  /// <summary>
  /// Schema order list
  /// </summary>
  protected virtual ImmutableArray<string> SchemaNodeOrder => ImmutableArray<string>.Empty;

  internal XmlNode CreateNode(string path) {
    if (path == "") {
      return TopNode;
    }
    return CreateNode(path, false);
  }

  internal XmlNode CreateNode(string path, bool insertFirst) {
    XmlNode node = TopNode;
    XmlNode prependNode = null;
    foreach (string subPath in path.Split('/')) {
      XmlNode subNode = node.SelectSingleNode(subPath, NameSpaceManager);
      if (subNode == null) {
        string nodeName;
        string nodePrefix;

        string nameSpaceUri;
        string[] nameSplit = subPath.Split(':');

        if (SchemaNodeOrder.Length > 0 && subPath[0] != '@') {
          insertFirst = false;
          prependNode = GetPrependNode(subPath, node);
        }

        if (nameSplit.Length > 1) {
          nodePrefix = nameSplit[0];
          if (nodePrefix[0] == '@') {
            nodePrefix = nodePrefix.Substring(1, nodePrefix.Length - 1);
          }
          nameSpaceUri = NameSpaceManager.LookupNamespace(nodePrefix);
          nodeName = nameSplit[1];
        } else {
          nodePrefix = "";
          nameSpaceUri = "";
          nodeName = nameSplit[0];
        }
        if (subPath.StartsWith("@")) {
          XmlAttribute addedAtt = node.OwnerDocument.CreateAttribute(
              subPath.Substring(1, subPath.Length - 1),
              nameSpaceUri); //nameSpaceURI
          node.Attributes.Append(addedAtt);
        } else {
          if (nodePrefix == "") {
            subNode = node.OwnerDocument.CreateElement(nodeName, nameSpaceUri);
          } else {
            if (nodePrefix == ""
                || (node.OwnerDocument != null
                        && node.OwnerDocument.DocumentElement != null
                        && node.OwnerDocument.DocumentElement.NamespaceURI == nameSpaceUri
                        && node.OwnerDocument.DocumentElement.Prefix == "")) {
              subNode = node.OwnerDocument.CreateElement(nodeName, nameSpaceUri);
            } else {
              subNode = node.OwnerDocument.CreateElement(nodePrefix, nodeName, nameSpaceUri);
            }
          }
          if (prependNode != null) {
            node.InsertBefore(subNode, prependNode);
            prependNode = null;
          } else if (insertFirst) {
            node.PrependChild(subNode);
          } else {
            node.AppendChild(subNode);
          }
        }
      }
      node = subNode;
    }
    return node;
  }

  /// <summary>
  /// Options to insert a node in the XmlDocument
  /// </summary>
  internal enum eNodeInsertOrder {
    /// <summary>
    /// Insert as first node of "topNode"
    /// </summary>
    First,

    /// <summary>
    /// Insert as the last child of "topNode"
    /// </summary>
    Last,

    /// <summary>
    /// Insert after the "referenceNode"
    /// </summary>
    After,

    /// <summary>
    /// Insert before the "referenceNode"
    /// </summary>
    Before,

    /// <summary>
    /// Use the Schema List to insert in the right order. If the Schema list
    /// is null or empty, consider "Last" as the selected option
    /// </summary>
    SchemaOrder,
  }

  /// <summary>
  /// Create a complex node. Insert the node according to the <paramref name="path"/>
  /// using the <paramref name="topNode"/> as the parent
  /// </summary>
  /// <param name="topNode"></param>
  /// <param name="path"></param>
  /// <returns></returns>
  internal XmlNode CreateComplexNode(XmlNode topNode, string path) {
    return CreateComplexNode(topNode, path, eNodeInsertOrder.SchemaOrder, null);
  }

  /// <summary>
  /// Creates complex XML nodes
  /// </summary>
  /// <remarks>
  /// 1. "d:conditionalFormatting"
  ///		1.1. Creates/find the first "conditionalFormatting" node
  ///
  /// 2. "d:conditionalFormatting/@sqref"
  ///		2.1. Creates/find the first "conditionalFormatting" node
  ///		2.2. Creates (if not exists) the @sqref attribute
  ///
  /// 3. "d:conditionalFormatting/@id='7'/@sqref='A9:B99'"
  ///		3.1. Creates/find the first "conditionalFormatting" node
  ///		3.2. Creates/update its @id attribute to "7"
  ///		3.3. Creates/update its @sqref attribute to "A9:B99"
  ///
  /// 4. "d:conditionalFormatting[@id='7']/@sqref='X1:X5'"
  ///		4.1. Creates/find the first "conditionalFormatting" node with @id=7
  ///		4.2. Creates/update its @sqref attribute to "X1:X5"
  ///
  /// 5. "d:conditionalFormatting[@id='7']/@id='8'/@sqref='X1:X5'/d:cfRule/@id='AB'"
  ///		5.1. Creates/find the first "conditionalFormatting" node with @id=7
  ///		5.2. Set its @id attribute to "8"
  ///		5.2. Creates/update its @sqref attribute and set it to "X1:X5"
  ///		5.3. Creates/find the first "cfRule" node (inside the node)
  ///		5.4. Creates/update its @id attribute to "AB"
  ///
  /// 6. "d:cfRule/@id=''"
  ///		6.1. Creates/find the first "cfRule" node
  ///		6.1. Remove the @id attribute
  ///	</remarks>
  /// <param name="topNode"></param>
  /// <param name="path"></param>
  /// <param name="nodeInsertOrder"></param>
  /// <param name="referenceNode"></param>
  /// <returns>The last node creates/found</returns>
  internal XmlNode CreateComplexNode(
      XmlNode topNode,
      string path,
      eNodeInsertOrder nodeInsertOrder,
      XmlNode referenceNode) {
    // Path is obrigatory
    if ((path == null) || (path == string.Empty)) {
      return topNode;
    }

    XmlNode node = topNode;

    //TODO: BUG: when the "path" contains "/" in an attrribue value, it gives an error.

    // Separate the XPath to Nodes and Attributes
    foreach (string subPath in path.Split('/')) {
      // The subPath can be any one of those:
      // nodeName
      // x:nodeName
      // nodeName[find criteria]
      // x:nodeName[find criteria]
      // @attribute
      // @attribute='attribute value'

      // Check if the subPath has at least one character
      if (subPath.Length > 0) {
        // Check if the subPath is an attribute (with or without value)
        if (subPath.StartsWith("@")) {
          // @attribute										--> Create attribute
          // @attribute=''								--> Remove attribute
          // @attribute='attribute value' --> Create attribute + update value
          string[] attributeSplit = subPath.Split('=');
          string attributeName = attributeSplit[0].Substring(1, attributeSplit[0].Length - 1);
          string attributeValue = null; // Null means no attribute value

          // Check if we have an attribute value to set
          if (attributeSplit.Length > 1) {
            // Remove the ' or " from the attribute value
            attributeValue = attributeSplit[1].Replace("'", "").Replace("\"", "");
          }

          // Get the attribute (if exists)
          XmlAttribute attribute = (XmlAttribute)(node.Attributes.GetNamedItem(attributeName));

          // Remove the attribute if value is empty (not null)
          if (attributeValue == string.Empty) {
            // Only if the attribute exists
            if (attribute != null) {
              node.Attributes.Remove(attribute);
            }
          } else {
            // Create the attribue if does not exists
            if (attribute == null) {
              // Create the attribute
              attribute = node.OwnerDocument.CreateAttribute(attributeName);

              // Add it to the current node
              node.Attributes.Append(attribute);
            }

            // Update the attribute value
            if (attributeValue != null) {
              node.Attributes[attributeName].Value = attributeValue;
            }
          }
        } else {
          // nodeName
          // x:nodeName
          // nodeName[find criteria]
          // x:nodeName[find criteria]

          // Look for the node (with or without filter criteria)
          XmlNode subNode = node.SelectSingleNode(subPath, NameSpaceManager);

          // Check if the node does not exists
          if (subNode == null) {
            string nodeName;
            string nodePrefix;
            string[] nameSplit = subPath.Split(':');
            string nameSpaceUri;

            // Check if the name has a prefix like "d:nodeName"
            if (nameSplit.Length > 1) {
              nodePrefix = nameSplit[0];
              nameSpaceUri = NameSpaceManager.LookupNamespace(nodePrefix);
              nodeName = nameSplit[1];
            } else {
              nodePrefix = string.Empty;
              nameSpaceUri = string.Empty;
              nodeName = nameSplit[0];
            }

            // Check if we have a criteria part in the node name
            if (nodeName.IndexOf("[") > 0) {
              // remove the criteria from the node name
              nodeName = nodeName.Substring(0, nodeName.IndexOf("["));
            }

            if (nodePrefix == string.Empty) {
              subNode = node.OwnerDocument.CreateElement(nodeName, nameSpaceUri);
            } else {
              if (node.OwnerDocument != null
                  && node.OwnerDocument.DocumentElement != null
                  && node.OwnerDocument.DocumentElement.NamespaceURI == nameSpaceUri
                  && node.OwnerDocument.DocumentElement.Prefix == string.Empty) {
                subNode = node.OwnerDocument.CreateElement(nodeName, nameSpaceUri);
              } else {
                subNode = node.OwnerDocument.CreateElement(nodePrefix, nodeName, nameSpaceUri);
              }
            }

            // Check if we need to use the "SchemaOrder"
            if (nodeInsertOrder == eNodeInsertOrder.SchemaOrder) {
              // Check if the Schema Order List is empty
              if (SchemaNodeOrder.Length == 0) {
                // Use the "Insert Last" option when Schema Order List is empty
                nodeInsertOrder = eNodeInsertOrder.Last;
              } else {
                // Find the prepend node in order to insert
                referenceNode = GetPrependNode(nodeName, node);

                if (referenceNode != null) {
                  nodeInsertOrder = eNodeInsertOrder.Before;
                } else {
                  nodeInsertOrder = eNodeInsertOrder.Last;
                }
              }
            }

            switch (nodeInsertOrder) {
              case eNodeInsertOrder.After:
                node.InsertAfter(subNode, referenceNode);
                referenceNode = null;
                break;

              case eNodeInsertOrder.Before:
                node.InsertBefore(subNode, referenceNode);
                referenceNode = null;
                break;

              case eNodeInsertOrder.First:
                node.PrependChild(subNode);
                break;

              case eNodeInsertOrder.Last:
                node.AppendChild(subNode);
                break;
            }
          }

          // Make the newly created node the top node when the rest of the path
          // is being evaluated. So newly created nodes will be the children of the
          // one we just created.
          node = subNode;
        }
      }
    }

    // Return the last created/found node
    return node;
  }

  /// <summary>
  /// return Prepend node
  /// </summary>
  /// <param name="nodeName">name of the node to check</param>
  /// <param name="node">Topnode to check children</param>
  /// <returns></returns>
  private XmlNode GetPrependNode(string nodeName, XmlNode node) {
    int pos = GetNodePos(nodeName);
    if (pos < 0) {
      return null;
    }
    XmlNode prependNode = null;
    foreach (XmlNode childNode in node.ChildNodes) {
      int childPos = GetNodePos(childNode.Name);
      if (childPos
          > -1) //Found?
      {
        if (childPos
            > pos) //Position is before
        {
          prependNode = childNode;
          break;
        }
      }
    }
    return prependNode;
  }

  private int GetNodePos(string nodeName) {
    int ix = nodeName.IndexOf(":");
    if (ix > 0) {
      nodeName = nodeName.Substring(ix + 1, nodeName.Length - (ix + 1));
    }
    for (int i = 0; i < SchemaNodeOrder.Length; i++) {
      if (nodeName == SchemaNodeOrder[i]) {
        return i;
      }
    }
    return -1;
  }

  internal void DeleteAllNode(string path) {
    string[] split = path.Split('/');
    XmlNode node = TopNode;
    foreach (string s in split) {
      node = node.SelectSingleNode(s, NameSpaceManager);
      if (node != null) {
        if (node is XmlAttribute attribute) {
          attribute.OwnerElement.Attributes.Remove(attribute);
        } else {
          node.ParentNode.RemoveChild(node);
        }
      } else {
        break;
      }
    }
  }

  internal void DeleteNode(string path) {
    var node = TopNode.SelectSingleNode(path, NameSpaceManager);
    if (node != null) {
      if (node is XmlAttribute att) {
        att.OwnerElement.Attributes.Remove(att);
      } else {
        node.ParentNode.RemoveChild(node);
      }
    }
  }

  internal void SetXmlNodeString(string path, string value) {
    SetXmlNodeString(TopNode, path, value, false, false);
  }

  internal void SetXmlNodeString(string path, string value, bool removeIfBlank) {
    SetXmlNodeString(TopNode, path, value, removeIfBlank, false);
  }

  internal void SetXmlNodeString(XmlNode node, string path, string value, bool removeIfBlank) {
    SetXmlNodeString(node, path, value, removeIfBlank, false);
  }

  internal void SetXmlNodeString(
      XmlNode node,
      string path,
      string value,
      bool removeIfBlank,
      bool insertFirst) {
    if (node == null) {
      return;
    }
    if (value == "" && removeIfBlank) {
      DeleteAllNode(path);
    } else {
      XmlNode nameNode = node.SelectSingleNode(path, NameSpaceManager);
      if (nameNode == null) {
        CreateNode(path, insertFirst);
        nameNode = node.SelectSingleNode(path, NameSpaceManager);
      }
      //if (nameNode.InnerText != value) HasChanged();
      nameNode.InnerText = value;
    }
  }

  internal void SetXmlNodeBool(string path, bool value) {
    SetXmlNodeString(TopNode, path, value ? "1" : "0", false, false);
  }

  internal void SetXmlNodeBool(string path, bool value, bool removeIf) {
    if (value == removeIf) {
      var node = TopNode.SelectSingleNode(path, NameSpaceManager);
      if (node != null) {
        if (node is XmlAttribute attribute) {
          var elem = attribute.OwnerElement;
          elem.ParentNode.RemoveChild(elem);
        } else {
          TopNode.RemoveChild(node);
        }
      }
    } else {
      SetXmlNodeString(TopNode, path, value ? "1" : "0", false, false);
    }
  }

  internal bool ExistNode(string path) {
    if (TopNode == null || TopNode.SelectSingleNode(path, NameSpaceManager) == null) {
      return false;
    }
    return true;
  }

  internal bool? GetXmlNodeBoolNullable(string path) {
    var value = GetXmlNodeString(path);
    if (string.IsNullOrEmpty(value)) {
      return null;
    }
    return GetXmlNodeBool(path);
  }

  internal bool GetXmlNodeBool(string path) {
    return GetXmlNodeBool(path, false);
  }

  internal bool GetXmlNodeBool(string path, bool blankValue) {
    string value = GetXmlNodeString(path);
    if (value == "1"
        || value == "-1"
        || value.Equals("true", StringComparison.InvariantCultureIgnoreCase)) {
      return true;
    }
    if (value == "") {
      return blankValue;
    }
    return false;
  }

  internal int GetXmlNodeInt(string path) {
    if (int.TryParse(GetXmlNodeString(path), out var i)) {
      return i;
    }
    return int.MinValue;
  }

  internal int? GetXmlNodeIntNull(string path) {
    string s = GetXmlNodeString(path);
    if (s != "" && int.TryParse(s, out var i)) {
      return i;
    }
    return null;
  }

  internal decimal GetXmlNodeDecimal(string path) {
    if (decimal.TryParse(
        GetXmlNodeString(path),
        NumberStyles.Any,
        CultureInfo.InvariantCulture,
        out var d)) {
      return d;
    }
    return 0;
  }

  internal decimal? GetXmlNodeDecimalNull(string path) {
    if (decimal.TryParse(
        GetXmlNodeString(path),
        NumberStyles.Any,
        CultureInfo.InvariantCulture,
        out var d)) {
      return d;
    }
    return null;
  }

  internal double? GetXmlNodeDoubleNull(string path) {
    string s = GetXmlNodeString(path);
    if (s == "") {
      return null;
    }
    if (double.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out var v)) {
      return v;
    }
    return null;
  }

  internal double GetXmlNodeDouble(string path) {
    string s = GetXmlNodeString(path);
    if (s == "") {
      return double.NaN;
    }
    if (double.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out var v)) {
      return v;
    }
    return double.NaN;
  }

  internal string GetXmlNodeString(XmlNode node, string path) {
    if (node == null) {
      return "";
    }

    XmlNode nameNode = node.SelectSingleNode(path, NameSpaceManager);

    if (nameNode != null) {
      if (nameNode.NodeType == XmlNodeType.Attribute) {
        return nameNode.Value ?? "";
      }
      return nameNode.InnerText;
    }
    return "";
  }

  internal string GetXmlNodeString(string path) {
    return GetXmlNodeString(TopNode, path);
  }

  internal static void LoadXmlSafe(XmlDocument xmlDoc, Stream stream) {
    XmlReaderSettings settings = new XmlReaderSettings();
    //Disable entity parsing (to aviod xmlbombs, External Entity Attacks etc).
    settings.ProhibitDtd = true;
    XmlReader reader = XmlReader.Create(stream, settings);
    xmlDoc.Load(reader);
  }

  internal static void LoadXmlSafe(XmlDocument xmlDoc, string xml, Encoding encoding) {
    var stream = new MemoryStream(encoding.GetBytes(xml));
    LoadXmlSafe(xmlDoc, stream);
  }
}
