/*******************************************************************************
 * 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.Globalization;
using System.IO;
using System.Text;
using System.Xml;
using OfficeOpenXml.Packaging;
using OfficeOpenXml.Style;

namespace OfficeOpenXml;

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

  private string[] _schemaNodeOrder;

  /// <summary>
  /// Schema order list
  /// </summary>
  internal string[] SchemaNodeOrder {
    get => _schemaNodeOrder;
    set => _schemaNodeOrder = value;
  }

  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 != null && 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 SchemaOrder
  /// using the TopNode as the parent
  /// </summary>
  /// <param name="path"></param>
  /// <returns></returns>
  internal XmlNode CreateComplexNode(string path) {
    return CreateComplexNode(TopNode, path, eNodeInsertOrder.SchemaOrder, null);
  }

  /// <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;
    string nameSpaceUri = string.Empty;

    //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(':');
            nameSpaceUri = string.Empty;

            // 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 == null) || (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 DeleteTopNode() {
    TopNode.ParentNode.RemoveChild(TopNode);
  }

  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) {
    SetXmlNodeString(node, path, value, false, 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 Uri GetNewUri(ZipPackage package, string sUri) {
    return GetNewUri(package, sUri, 1);
  }

  internal static Uri GetNewUri(ZipPackage package, string sUri, int id) {
    Uri uri;
    do {
      uri = new(string.Format(sUri, id++), UriKind.Relative);
    } while (package.PartExists(uri));
    return uri;
  }

  /// <summary>
  /// Insert the new node before any of the nodes in the comma separeted list
  /// </summary>
  /// <param name="parentNode">Parent node</param>
  /// <param name="beforeNodes">comma separated list containing nodes to insert after. Left to right order</param>
  /// <param name="newNode">The new node to be inserterd</param>
  internal void InserAfter(XmlNode parentNode, string beforeNodes, XmlNode newNode) {
    string[] nodePaths = beforeNodes.Split(',');

    foreach (string nodePath in nodePaths) {
      XmlNode node = parentNode.SelectSingleNode(nodePath, NameSpaceManager);
      if (node != null) {
        parentNode.InsertAfter(newNode, node);
        return;
      }
    }
    parentNode.InsertAfter(newNode, null);
  }

  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);
  }
}
