/*******************************************************************************
 * 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		Added		25-Oct-2012
 *******************************************************************************/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;

namespace AppsheetEpplus;

/// <summary>
/// Specifies whether the target is inside or outside the System.IO.Packaging.Package.
/// </summary>
public enum TargetMode {
  /// <summary>
  /// The relationship references a part that is inside the package.
  /// </summary>
  Internal = 0,

  /// <summary>
  /// The relationship references a resource that is external to the package.
  /// </summary>
  External = 1,
}

/// <summary>
/// Represent an OOXML Zip package.
/// </summary>
internal class ZipPackage : ZipPackageRelationshipBase {
  internal class ContentType {
    internal string Name;
    internal bool IsExtension;
    internal string Match;

    public ContentType(string name, bool isExtension, string match) {
      Name = name;
      IsExtension = isExtension;
      Match = match;
    }
  }

  private readonly Dictionary<string, ZipPackagePart> Parts = new(
      StringComparer.InvariantCultureIgnoreCase);
  internal Dictionary<string, ContentType> _contentTypes = new(
      StringComparer.InvariantCultureIgnoreCase);

  internal ZipPackage() {
    AddNew();
  }

  private void AddNew() {
    _contentTypes.Add("xml", new(ExcelPackage._schemaXmlExtension, true, "xml"));
    _contentTypes.Add("rels", new(ExcelPackage._schemaRelsExtension, true, "rels"));
  }

  internal ZipPackage(Stream stream) {
    bool hasContentTypeXml = false;
    if (stream == null || stream.Length == 0) {
      AddNew();
    } else {
      var rels = new Dictionary<string, ZipArchiveEntry>();
      stream.Seek(0, SeekOrigin.Begin);
      using var zip = new ZipArchive(stream, ZipArchiveMode.Read, leaveOpen: true);
      foreach (var e in zip.Entries) {
        if (e.Length > 0) {
          if (e.FullName.Equals(
              "[content_types].xml",
              StringComparison.InvariantCultureIgnoreCase)) {
            using var inputStream = e.Open();
            AddContentTypes(inputStream);
            hasContentTypeXml = true;
          } else if (e.FullName.Equals(
              "_rels/.rels",
              StringComparison.InvariantCultureIgnoreCase)) {
            using var inputStream = e.Open();
            ReadRelation(inputStream, "");
          } else {
            if (e.FullName.EndsWith(".rels", StringComparison.InvariantCultureIgnoreCase)) {
              rels.Add(GetUriKey(e.FullName), e);
            } else {
              var data = new byte[e.Length];
              using var inputStream = e.Open();
              inputStream.ReadExactly(data);
              var part = new ZipPackagePart(
                  this,
                  e,
                  ImmutableCollectionsMarshal.AsImmutableArray(data));
              Parts.Add(GetUriKey(e.FullName), part);
            }
          }
        }
      }
      foreach (var p in Parts) {
        string name = Path.GetFileName(p.Key);
        string extension = Path.GetExtension(p.Key);
        string relFile = string.Format(
            "{0}_rels/{1}.rels",
            p.Key.Substring(0, p.Key.Length - name.Length),
            name);
        if (rels.TryGetValue(relFile, out var zipArchiveEntry)) {
          using var inputStream = zipArchiveEntry.Open();
          p.Value.ReadRelation(inputStream, p.Value.Uri.OriginalString);
        }
        if (_contentTypes.TryGetValue(p.Key, out var type)) {
          p.Value.ContentType = type.Name;
        } else if (extension.Length > 1 && _contentTypes.ContainsKey(extension.Substring(1))) {
          p.Value.ContentType = _contentTypes[extension.Substring(1)].Name;
        }
      }
      if (!hasContentTypeXml) {
        throw new InvalidDataException("The file is not an valid Package file.");
      }
    }
  }

  private void AddContentTypes(Stream inputStream) {
    var doc = new XmlDocument();
    XmlHelper.LoadXmlSafe(doc, inputStream);

    foreach (XmlElement c in doc.DocumentElement.ChildNodes) {
      ContentType ct;
      if (string.IsNullOrEmpty(c.GetAttribute("Extension"))) {
        ct = new(c.GetAttribute("ContentType"), false, c.GetAttribute("PartName"));
      } else {
        ct = new(c.GetAttribute("ContentType"), true, c.GetAttribute("Extension"));
      }
      _contentTypes.Add(GetUriKey(ct.Match), ct);
    }
  }

  internal void CreatePart(Uri partUri, string contentType, Action<StreamWriter> saveHandler) {
    if (PartExists(partUri)) {
      throw (new InvalidOperationException("Part already exist"));
    }

    var part = new ZipPackagePart(this, partUri, contentType, saveHandler);
    _contentTypes.Add(
        GetUriKey(part.Uri.OriginalString),
        new(contentType, false, part.Uri.OriginalString));
    Parts.Add(GetUriKey(part.Uri.OriginalString), part);
  }

  internal ZipPackagePart GetPart(Uri partUri) {
    if (PartExists(partUri)) {
      return Parts
          .Single(x =>
              x.Key.Equals(
                  GetUriKey(partUri.OriginalString),
                  StringComparison.InvariantCultureIgnoreCase))
          .Value;
    }
    throw (new InvalidOperationException("Part does not exist."));
  }

  internal string GetUriKey(string uri) {
    string ret = uri;
    if (ret[0] != '/') {
      ret = "/" + ret;
    }
    return ret;
  }

  internal bool PartExists(Uri partUri) {
    var uriKey = GetUriKey(partUri.OriginalString.ToLower(CultureInfo.InvariantCulture));
    return Parts.Keys.Any(x => x.Equals(uriKey, StringComparison.InvariantCultureIgnoreCase));
  }

  internal void DeletePart(Uri uri) {
    var delList = new List<object[]>();
    foreach (var p in Parts.Values) {
      foreach (var r in p.GetRelationships()) {
        if (UriHelper
            .ResolvePartUri(p.Uri, r.TargetUri)
            .OriginalString.Equals(
                uri.OriginalString,
                StringComparison.InvariantCultureIgnoreCase)) {
          delList.Add([r.Id, p]);
        }
      }
    }
    foreach (var o in delList) {
      ((ZipPackagePart)o[1]).DeleteRelationship(o[0].ToString());
    }
    var rels = GetPart(uri).GetRelationships();
    while (rels.Count > 0) {
      rels.Remove(rels.First().Id);
    }
    _contentTypes.Remove(GetUriKey(uri.OriginalString));
    //remove all relations
    Parts.Remove(GetUriKey(uri.OriginalString));
  }

  internal void Save(Stream stream) {
    using var zipArchive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true);
    // Content types
    var contentTypesEntry = zipArchive.CreateEntry("[Content_Types].xml");
    using (var contentTypesWriter = new StreamWriter(contentTypesEntry.Open())) {
      contentTypesWriter.Write(GetContentTypeXml());
    }
    // Top Rels
    _rels.WriteZip(zipArchive, "_rels/.rels");
    ZipPackagePart ssPart = null;
    foreach (var part in Parts.Values) {
      if (part.ContentType != ExcelPackage._contentTypeSharedString) {
        part.WriteZip(zipArchive);
      } else {
        ssPart = part;
      }
    }
    //Shared strings must be saved after all worksheets. The ss dictionary is populated when that workheets are saved (to get the best performance).
    if (ssPart != null) {
      ssPart.WriteZip(zipArchive);
    }
  }

  private string GetContentTypeXml() {
    StringBuilder xml = new StringBuilder(
        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">");
    foreach (ContentType ct in _contentTypes.Values) {
      if (ct.IsExtension) {
        xml.Append($"<Default ContentType=\"{ct.Name}\" Extension=\"{ct.Match}\"/>");
      } else {
        xml.Append($"<Override ContentType=\"{ct.Name}\" PartName=\"{GetUriKey(ct.Match)}\" />");
      }
    }
    xml.Append("</Types>");
    return xml.ToString();
  }
}
