﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksum;
using System;

namespace Baidu.VR.DepthpanoEditor
{
    public static class DepthpanoEditorZipHelper
	{
        public static bool ZipFiles(string zipedFile, string directoryRoot, IEnumerable<string> pathsToZip)
        {
            if(directoryRoot == null)

            if (string.IsNullOrEmpty(zipedFile)
                || string.IsNullOrEmpty(directoryRoot)
                || pathsToZip == null)
                return false;

            {//修改与检查根目录
                directoryRoot.Replace('/', '\\');
                if (!Directory.Exists(directoryRoot))
                {
                    Debug.LogErrorFormat("Directory root not exist: {0}", directoryRoot);
                    return false;
                }
            }

            {//为导出Zip文件创建目录
                string zipDirectory = Path.GetDirectoryName(zipedFile);
                if (string.IsNullOrEmpty(zipDirectory))
                {
                    Debug.LogErrorFormat("Zip file name illegal: {0}", directoryRoot);
                    return false;
                }
                if (!Directory.Exists(zipDirectory))
                    Directory.CreateDirectory(zipDirectory);
            }

            if (directoryRoot[directoryRoot.Length - 1] != '\\')
                directoryRoot += "\\";

            using (var fs = File.Open(zipedFile, FileMode.OpenOrCreate))
            {
                if (fs == null)
                {
                    Debug.LogErrorFormat("Fail to open file: {0}.", zipedFile);
                    return false;
                }

                using (ZipOutputStream ZipStream = new ZipOutputStream(fs))
                {
                    if (ZipStream == null)
                    {
                        Debug.LogError("Fail to create ZipOutputStream.");
                        return false;
                    }

                    foreach (var path in pathsToZip)
                    {
                        if (string.IsNullOrEmpty(path))
                            continue;

                        CreateZipFile(path,
                            ZipStream, directoryRoot);
                    }

                    ZipStream.Finish();
                    ZipStream.Close();
                }
            }
            return true;
        }

        /// <summary>
        /// 压缩文件
        /// </summary>
        /// <param name="sourcePath">需要压缩的文件或者文件夹路径</param>
        /// <param name="zipStream">压缩结果名称以及路径</param>
        /// <param name="fileDirectory">需要压缩的文件或者文件夹初始路径</param>
        public static void CreateZipFile(string sourcePath, ZipOutputStream zipStream, string fileDirectory)
        {
            Crc32 crc = new Crc32();
            if (Directory.Exists(sourcePath))//文件夹
            {
                string[] filesArray = Directory.GetFileSystemEntries(sourcePath);

                if (filesArray.Length == 0)//目录下无文件或者文件夹创建空目录
                {
                    string tempFile = sourcePath.Substring(fileDirectory.LastIndexOf("\\") + 1);
                    ZipEntry entry = new ZipEntry(tempFile + "\\");//需要加\才是创建文件夹
                    zipStream.PutNextEntry(entry);
                    return;
                }
                foreach (string file in filesArray)
                {
                    CreateZipFile(file, zipStream, fileDirectory);
                }
            }
            else if (File.Exists(sourcePath))//文件
            {
                FileStream fileStream = File.OpenRead(sourcePath);
                byte[] buffer = new byte[fileStream.Length];
                fileStream.Read(buffer, 0, buffer.Length);
                string tempFile = sourcePath.Substring(fileDirectory.LastIndexOf("\\") + 1);
                ZipEntry entry = new ZipEntry(tempFile);
                entry.ExternalFileAttributes = (int)File.GetAttributes(sourcePath);
                entry.DateTime = DateTime.Now;
                entry.Size = fileStream.Length;
                fileStream.Close();
                crc.Reset();
                crc.Update(buffer);
                entry.Crc = crc.Value;
                zipStream.PutNextEntry(entry);
                zipStream.Write(buffer, 0, buffer.Length);
            }
        }
    }
}
