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