/*******************************************************************************
 * 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.Text;
using System.Xml;
using OfficeOpenXml.Utils;

namespace OfficeOpenXml.Packaging;

/// <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>
public 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 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 {
              using var inputStream = e.Open();
              var part = new ZipPackagePart(this, e);
              part.Stream = new();
              inputStream.CopyTo(part.Stream);
              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 ZipPackagePart CreatePart(Uri partUri, string contentType) {
    return CreatePart(partUri, contentType, CompressionLevel.Default);
  }

  internal ZipPackagePart CreatePart(
      Uri partUri,
      string contentType,
      CompressionLevel compressionLevel) {
    if (PartExists(partUri)) {
      throw (new InvalidOperationException("Part already exist"));
    }

    var part = new ZipPackagePart(this, partUri, contentType, compressionLevel);
    _contentTypes.Add(
        GetUriKey(part.Uri.OriginalString),
        new(contentType, false, part.Uri.OriginalString));
    Parts.Add(GetUriKey(part.Uri.OriginalString), part);
    return 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(new object[] { 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);
    }
    rels = null;
    _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);
    /**** ContentType****/
    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);
    }
    //return ms;
  }

  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.AppendFormat("<Default ContentType=\"{0}\" Extension=\"{1}\"/>", ct.Name, ct.Match);
      } else {
        xml.AppendFormat(
            "<Override ContentType=\"{0}\" PartName=\"{1}\" />",
            ct.Name,
            GetUriKey(ct.Match));
      }
    }
    xml.Append("</Types>");
    return xml.ToString();
  }

  private CompressionLevel _compression = CompressionLevel.Default;

  public CompressionLevel Compression {
    get => _compression;
    set {
      foreach (var part in Parts.Values) {
        if (part.CompressionLevel == _compression) {
          part.CompressionLevel = value;
        }
      }
      _compression = value;
    }
  }
}
