using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;

namespace CrazyStudio.Core.Common.ZipHelper
{
    public static class ZipHelper
    {
        /// <summary>
        /// 将Zip文件描述对象打包成Zip文件，并返回字节数组
        /// </summary>
        /// <param name="zipFiles">Zip文件描述对象数组</param>
        /// <returns></returns>
        public static byte[] PackedZip(this List<ZipFile> zipFiles)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
                {
                    foreach (var zipFile in zipFiles)
                    {
                        zipArchive.AddFile(zipFile.RelativePath, zipFile.Content);
                    }
                }

                memoryStream.Seek(0, SeekOrigin.Begin); //这句要在using ZipArchive外面，否则压缩文件会被损坏
                return memoryStream.ToBytes();
            }
        }

        /// <summary>
        /// 向Zip文件中添加文件
        /// </summary>
        /// <param name="zipArchive"></param>
        /// <param name="relativePath">相对路径</param>
        /// <param name="bytes">文件内容</param>
        /// <returns></returns>
        private static bool AddFile(this ZipArchive zipArchive, string relativePath, byte[] bytes)
        {
            try
            {
                ZipArchiveEntry entry = zipArchive.CreateEntry(relativePath);
                using (Stream entryStream = entry.Open())
                {
                    entryStream.Write(bytes, 0, bytes.Length);
                }

                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 将流转成字节数组
        /// </summary>
        /// <param name="stream">文件流</param>
        /// <returns></returns>
        public static byte[] ToBytes(this Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }
    }
}
