/*******************************************************************************
 * 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                      Total rewrite               2010-03-01
 * Jan K�llman		    License changed GPL-->LGPL  2011-12-27
 * Raziq York                       Added Created & Modified    2014-08-20
 *******************************************************************************/

using System;
using System.Globalization;
using System.IO;
using System.Xml;
using OfficeOpenXml.Packaging;
using OfficeOpenXml.Utils;

namespace OfficeOpenXml;

/// <summary>
/// Provides access to the properties bag of the package
/// </summary>
public sealed class OfficeProperties : XmlHelper {
  private XmlDocument _xmlPropertiesCore;
  private XmlDocument _xmlPropertiesExtended;
  private XmlDocument _xmlPropertiesCustom;

  private Uri _uriPropertiesCore = new("/docProps/core.xml", UriKind.Relative);
  private Uri _uriPropertiesExtended = new("/docProps/app.xml", UriKind.Relative);
  private Uri _uriPropertiesCustom = new("/docProps/custom.xml", UriKind.Relative);

  private XmlHelper _coreHelper;
  private XmlHelper _extendedHelper;
  private XmlHelper _customHelper;
  private ExcelPackage _package;

  /// <summary>
  /// Provides access to all the office document properties.
  /// </summary>
  /// <param name="package"></param>
  /// <param name="ns"></param>
  internal OfficeProperties(ExcelPackage package, XmlNamespaceManager ns)
      : base(ns) {
    _package = package;

    _coreHelper = XmlHelperFactory.Create(
        ns,
        CorePropertiesXml.SelectSingleNode("cp:coreProperties", NameSpaceManager));
    _extendedHelper = XmlHelperFactory.Create(ns, ExtendedPropertiesXml);
    _customHelper = XmlHelperFactory.Create(ns, CustomPropertiesXml);
  }

  /// <summary>
  /// Provides access to the XML document that holds all the code
  /// document properties.
  /// </summary>
  public XmlDocument CorePropertiesXml {
    get {
      if (_xmlPropertiesCore == null) {
        string xml = string.Format(
            "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><cp:coreProperties xmlns:cp=\"{0}\" xmlns:dc=\"{1}\" xmlns:dcterms=\"{2}\" xmlns:dcmitype=\"{3}\" xmlns:xsi=\"{4}\"></cp:coreProperties>",
            ExcelPackage._schemaCore,
            ExcelPackage._schemaDc,
            ExcelPackage._schemaDcTerms,
            ExcelPackage._schemaDcmiType,
            ExcelPackage._schemaXsi);

        _xmlPropertiesCore = GetXmlDocument(
            xml,
            _uriPropertiesCore,
            "application/vnd.openxmlformats-package.core-properties+xml",
            "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties");
      }
      return (_xmlPropertiesCore);
    }
  }

  private XmlDocument GetXmlDocument(
      string startXml,
      Uri uri,
      string contentType,
      string relationship) {
    XmlDocument xmlDoc;
    if (_package.Package.PartExists(uri)) {
      xmlDoc = _package.GetXmlFromUri(uri);
    } else {
      xmlDoc = new();
      xmlDoc.LoadXml(startXml);

      // Create a the part and add to the package
      ZipPackagePart part = _package.Package.CreatePart(uri, contentType);

      // Save it to the package
      StreamWriter stream = new StreamWriter(part.GetStream(FileMode.Create, FileAccess.Write));
      xmlDoc.Save(stream);
      //stream.Close();

      // create the relationship between the workbook and the new shared strings part
      _package.Package.CreateRelationship(
          UriHelper.GetRelativeUri(new("/xl", UriKind.Relative), uri),
          TargetMode.Internal,
          relationship);
    }
    return xmlDoc;
  }

  private const string _titlePath = "dc:title";

  /// <summary>
  /// Gets/sets the title property of the document (core property)
  /// </summary>
  public string Title {
    get => _coreHelper.GetXmlNodeString(_titlePath);
    set => _coreHelper.SetXmlNodeString(_titlePath, value);
  }

  private const string _subjectPath = "dc:subject";

  /// <summary>
  /// Gets/sets the subject property of the document (core property)
  /// </summary>
  public string Subject {
    get => _coreHelper.GetXmlNodeString(_subjectPath);
    set => _coreHelper.SetXmlNodeString(_subjectPath, value);
  }

  private const string _authorPath = "dc:creator";

  /// <summary>
  /// Gets/sets the author property of the document (core property)
  /// </summary>
  public string Author {
    get => _coreHelper.GetXmlNodeString(_authorPath);
    set => _coreHelper.SetXmlNodeString(_authorPath, value);
  }

  private const string _commentsPath = "dc:description";

  /// <summary>
  /// Gets/sets the comments property of the document (core property)
  /// </summary>
  public string Comments {
    get => _coreHelper.GetXmlNodeString(_commentsPath);
    set => _coreHelper.SetXmlNodeString(_commentsPath, value);
  }

  private const string _keywordsPath = "cp:keywords";

  /// <summary>
  /// Gets/sets the keywords property of the document (core property)
  /// </summary>
  public string Keywords {
    get => _coreHelper.GetXmlNodeString(_keywordsPath);
    set => _coreHelper.SetXmlNodeString(_keywordsPath, value);
  }

  private const string _lastModifiedByPath = "cp:lastModifiedBy";

  /// <summary>
  /// Gets/sets the lastModifiedBy property of the document (core property)
  /// </summary>
  public string LastModifiedBy {
    get => _coreHelper.GetXmlNodeString(_lastModifiedByPath);
    set => _coreHelper.SetXmlNodeString(_lastModifiedByPath, value);
  }

  private const string _lastPrintedPath = "cp:lastPrinted";

  /// <summary>
  /// Gets/sets the lastPrinted property of the document (core property)
  /// </summary>
  public string LastPrinted {
    get => _coreHelper.GetXmlNodeString(_lastPrintedPath);
    set => _coreHelper.SetXmlNodeString(_lastPrintedPath, value);
  }

  private const string _createdPath = "dcterms:created";

  /// <summary>
  /// Gets/sets the created property of the document (core property)
  /// </summary>
  public DateTime Created {
    get {
      DateTime date;
      return DateTime.TryParse(_coreHelper.GetXmlNodeString(_createdPath), out date)
          ? date
          : DateTime.MinValue;
    }
    set {
      var dateString = value.ToUniversalTime().ToString("s", CultureInfo.InvariantCulture) + "Z";
      _coreHelper.SetXmlNodeString(_createdPath, dateString);
      _coreHelper.SetXmlNodeString(_createdPath + "/@xsi:type", "dcterms:W3CDTF");
    }
  }

  private const string _categoryPath = "cp:category";

  /// <summary>
  /// Gets/sets the category property of the document (core property)
  /// </summary>
  public string Category {
    get => _coreHelper.GetXmlNodeString(_categoryPath);
    set => _coreHelper.SetXmlNodeString(_categoryPath, value);
  }

  private const string _contentStatusPath = "cp:contentStatus";

  /// <summary>
  /// Gets/sets the status property of the document (core property)
  /// </summary>
  public string Status {
    get => _coreHelper.GetXmlNodeString(_contentStatusPath);
    set => _coreHelper.SetXmlNodeString(_contentStatusPath, value);
  }

  /// <summary>
  /// Provides access to the XML document that holds the extended properties of the document (app.xml)
  /// </summary>
  public XmlDocument ExtendedPropertiesXml {
    get {
      if (_xmlPropertiesExtended == null) {
        _xmlPropertiesExtended = GetXmlDocument(
            string.Format(
                "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><Properties xmlns:vt=\"{0}\" xmlns=\"{1}\"></Properties>",
                ExcelPackage._schemaVt,
                ExcelPackage._schemaExtended),
            _uriPropertiesExtended,
            "application/vnd.openxmlformats-officedocument.extended-properties+xml",
            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties");
      }
      return (_xmlPropertiesExtended);
    }
  }

  private const string _applicationPath = "xp:Properties/xp:Application";

  /// <summary>
  /// Gets/Set the Application property of the document (extended property)
  /// </summary>
  public string Application {
    get => _extendedHelper.GetXmlNodeString(_applicationPath);
    set => _extendedHelper.SetXmlNodeString(_applicationPath, value);
  }

  private const string _hyperlinkBasePath = "xp:Properties/xp:HyperlinkBase";

  /// <summary>
  /// Gets/sets the HyperlinkBase property of the document (extended property)
  /// </summary>
  public Uri HyperlinkBase {
    get => new(_extendedHelper.GetXmlNodeString(_hyperlinkBasePath), UriKind.Absolute);
    set => _extendedHelper.SetXmlNodeString(_hyperlinkBasePath, value.AbsoluteUri);
  }

  private const string _appVersionPath = "xp:Properties/xp:AppVersion";

  /// <summary>
  /// Gets/Set the AppVersion property of the document (extended property)
  /// </summary>
  public string AppVersion {
    get => _extendedHelper.GetXmlNodeString(_appVersionPath);
    set => _extendedHelper.SetXmlNodeString(_appVersionPath, value);
  }

  private const string _companyPath = "xp:Properties/xp:Company";

  /// <summary>
  /// Gets/sets the Company property of the document (extended property)
  /// </summary>
  public string Company {
    get => _extendedHelper.GetXmlNodeString(_companyPath);
    set => _extendedHelper.SetXmlNodeString(_companyPath, value);
  }

  private const string _managerPath = "xp:Properties/xp:Manager";

  /// <summary>
  /// Gets/sets the Manager property of the document (extended property)
  /// </summary>
  public string Manager {
    get => _extendedHelper.GetXmlNodeString(_managerPath);
    set => _extendedHelper.SetXmlNodeString(_managerPath, value);
  }

  private const string _modifiedPath = "dcterms:modified";

  /// <summary>
  /// Gets/sets the modified property of the document (core property)
  /// </summary>
  public DateTime Modified {
    get {
      DateTime date;
      return DateTime.TryParse(_coreHelper.GetXmlNodeString(_modifiedPath), out date)
          ? date
          : DateTime.MinValue;
    }
    set {
      var dateString = value.ToUniversalTime().ToString("s", CultureInfo.InvariantCulture) + "Z";
      _coreHelper.SetXmlNodeString(_modifiedPath, dateString);
      _coreHelper.SetXmlNodeString(_modifiedPath + "/@xsi:type", "dcterms:W3CDTF");
    }
  }

  private string GetExtendedPropertyValue(string propertyName) {
    string retValue = null;
    string searchString = string.Format("xp:Properties/xp:{0}", propertyName);
    XmlNode node = ExtendedPropertiesXml.SelectSingleNode(searchString, NameSpaceManager);
    if (node != null) {
      retValue = node.InnerText;
    }
    return retValue;
  }

  /// <summary>
  /// Provides access to the XML document which holds the document's custom properties
  /// </summary>
  public XmlDocument CustomPropertiesXml {
    get {
      if (_xmlPropertiesCustom == null) {
        _xmlPropertiesCustom = GetXmlDocument(
            string.Format(
                "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><Properties xmlns:vt=\"{0}\" xmlns=\"{1}\"></Properties>",
                ExcelPackage._schemaVt,
                ExcelPackage._schemaCustom),
            _uriPropertiesCustom,
            "application/vnd.openxmlformats-officedocument.custom-properties+xml",
            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties");
      }
      return (_xmlPropertiesCustom);
    }
  }

  /// <summary>
  /// Gets the value of a custom property
  /// </summary>
  /// <param name="propertyName">The name of the property</param>
  /// <returns>The current value of the property</returns>
  public object GetCustomPropertyValue(string propertyName) {
    string searchString = string.Format("ctp:Properties/ctp:property[@name='{0}']", propertyName);
    XmlElement node =
        CustomPropertiesXml.SelectSingleNode(searchString, NameSpaceManager) as XmlElement;
    if (node != null) {
      string value = node.LastChild.InnerText;
      switch (node.LastChild.LocalName) {
        case "filetime":
          DateTime dt;
          if (DateTime.TryParse(value, out dt)) {
            return dt;
          }
          return null;
        case "i4":
          int i;
          if (int.TryParse(value, out i)) {
            return i;
          }
          return null;
        case "r8":
          double d;
          if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out d)) {
            return d;
          }
          return null;
        case "bool":
          if (value == "true") {
            return true;
          }
          if (value == "false") {
            return false;
          }
          return null;
        default:
          return value;
      }
    }
    return null;
  }

  /// <summary>
  /// Allows you to set the value of a current custom property or create your own custom property.
  /// </summary>
  /// <param name="propertyName">The name of the property</param>
  /// <param name="value">The value of the property</param>
  public void SetCustomPropertyValue(string propertyName, object value) {
    XmlNode allProps = CustomPropertiesXml.SelectSingleNode("ctp:Properties", NameSpaceManager);

    var prop = string.Format("ctp:Properties/ctp:property[@name='{0}']", propertyName);
    XmlElement node = CustomPropertiesXml.SelectSingleNode(prop, NameSpaceManager) as XmlElement;
    if (node == null) {
      int pid;
      var maxNode = CustomPropertiesXml.SelectSingleNode(
          "ctp:Properties/ctp:property[not(@pid <= preceding-sibling::ctp:property/@pid) and not(@pid <= following-sibling::ctp:property/@pid)]",
          NameSpaceManager);
      if (maxNode == null) {
        pid = 2;
      } else {
        if (!int.TryParse(maxNode.Attributes["pid"].Value, out pid)) {
          pid = 2;
        }
        pid++;
      }
      node = CustomPropertiesXml.CreateElement("property", ExcelPackage._schemaCustom);
      node.SetAttribute("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}");
      node.SetAttribute("pid", pid.ToString()); // custom property pid
      node.SetAttribute("name", propertyName);

      allProps.AppendChild(node);
    } else {
      while (node.ChildNodes.Count > 0) {
        node.RemoveChild(node.ChildNodes[0]);
      }
    }
    XmlElement valueElem;
    if (value is bool) {
      valueElem = CustomPropertiesXml.CreateElement("vt", "bool", ExcelPackage._schemaVt);
      valueElem.InnerText = value.ToString().ToLower(CultureInfo.InvariantCulture);
    } else if (value is DateTime) {
      valueElem = CustomPropertiesXml.CreateElement("vt", "filetime", ExcelPackage._schemaVt);
      valueElem.InnerText = ((DateTime)value).AddHours(-1).ToString("yyyy-MM-ddTHH:mm:ssZ");
    } else if (value is short || value is int) {
      valueElem = CustomPropertiesXml.CreateElement("vt", "i4", ExcelPackage._schemaVt);
      valueElem.InnerText = value.ToString();
    } else if (value is double || value is decimal || value is float || value is long) {
      valueElem = CustomPropertiesXml.CreateElement("vt", "r8", ExcelPackage._schemaVt);
      if (value is double) {
        valueElem.InnerText = ((double)value).ToString(CultureInfo.InvariantCulture);
      } else if (value is float) {
        valueElem.InnerText = ((float)value).ToString(CultureInfo.InvariantCulture);
      } else if (value is decimal) {
        valueElem.InnerText = ((decimal)value).ToString(CultureInfo.InvariantCulture);
      } else {
        valueElem.InnerText = value.ToString();
      }
    } else {
      valueElem = CustomPropertiesXml.CreateElement("vt", "lpwstr", ExcelPackage._schemaVt);
      valueElem.InnerText = value.ToString();
    }
    node.AppendChild(valueElem);
  }

  /// <summary>
  /// Saves the document properties back to the package.
  /// </summary>
  internal void Save() {
    if (_xmlPropertiesCore != null) {
      _package.SavePart(_uriPropertiesCore, _xmlPropertiesCore);
    }
    if (_xmlPropertiesExtended != null) {
      _package.SavePart(_uriPropertiesExtended, _xmlPropertiesExtended);
    }
    if (_xmlPropertiesCustom != null) {
      _package.SavePart(_uriPropertiesCustom, _xmlPropertiesCustom);
    }
  }
}
