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

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