using System;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

namespace RyzStudio.IO
{
    public class SharpZipLib
    {


        public static bool IsZipEncrypted(string filename)
        {
            bool rv = false;

            try
            {
                ZipInputStream readStream = new ZipInputStream(System.IO.File.OpenRead(filename));

                ZipEntry theEntry = null;
                while ((theEntry = readStream.GetNextEntry()) != null)
                {
                    if (theEntry.IsCrypted)
                    {
                        rv = true;
                    }

                    break;
                }

                readStream.Close();
                readStream.Dispose();
                readStream = null;
            }
            catch
            {
                // do nothing
            }

            return rv;
        }

        //public static void AddFile(ZipOutputStream zipStream, string filename, string prefixPath = null)
        //{
        //    byte[] buffer = new byte[4096];

        //    string f1 = "";
        //    if (prefixPath != null)
        //    {
        //        f1 = Path.GetDirectoryName(filename).TrimEnd('\\') + "\\";
        //        f1 = f1.Replace(prefixPath, "").TrimEnd('\\') + "\\";
        //        f1 = f1 + Path.GetFileName(filename);
        //        f1 = f1.TrimStart('\\');
        //    }

        //    ZipEntry entry = new ZipEntry(f1);
        //    entry.DateTime = DateTime.Now;

        //    zipStream.PutNextEntry(entry);

        //    FileStream fs = File.OpenRead(filename);

        //    int sourceBytes;

        //    do
        //    {
        //        sourceBytes = fs.Read(buffer, 0, buffer.Length);
        //        zipStream.Write(buffer, 0, sourceBytes);
        //    }
        //    while (sourceBytes > 0);
        //}

        //public static void AddFolder(ZipOutputStream zipstream, string folderpath, string prefixpath = null)
        //{
        //    foreach (string fn in Directory.GetFiles(folderpath, "*.*", System.IO.SearchOption.AllDirectories))
        //    {
        //        AddFile(zipstream, fn, prefixpath);
        //    }
        //}

        public static string ReadSingle(string filename, string password, string entryFilename)
        {
            string rv = null;

            int size = 2048;
            byte[] buffer = new byte[size];
            int bufferSize = 0;

            ZipEntry readEntry = null;

            try
            {
                ZipInputStream readStream = new ZipInputStream(File.OpenRead(filename));
                readStream.Password = password;

                while (true)
                {
                    readEntry = readStream.GetNextEntry();
                    if (readEntry == null)
                    {
                        break;
                    }

                    if (string.IsNullOrWhiteSpace(readEntry.Name))
                    {
                        continue;
                    }

                    if (!readEntry.IsFile)
                    {
                        continue;
                    }

                    if (!readEntry.Name.Equals(entryFilename))
                    {
                        continue;
                    }

                    MemoryStream ms = new MemoryStream();
                    buffer = new byte[size];
                    bufferSize = 0;

                    do
                    {
                        bufferSize = readStream.Read(buffer, 0, buffer.Length);
                        ms.Write(buffer, 0, bufferSize);
                    }
                    while (bufferSize > 0);

                    ms.Position = 0;

                    StreamReader sr = new StreamReader(ms);
                    rv = sr.ReadToEnd();

                    break;
                }

                readStream.Flush();
                readStream.Close();
                readStream.Dispose();
                readStream = null;
            }
            catch (Exception)
            {
                return rv;
            }

            return rv;
        }

        public static bool TestArchive(string filename, string password = null)
        {
            if (string.IsNullOrWhiteSpace(filename))
            {
                return false;
            }

            if (!File.Exists(filename))
            {
                return false;
            }

            ZipEntry readEntry = null;

            try
            {
                ZipInputStream readStream = new ZipInputStream(System.IO.File.OpenRead(filename));
                readStream.Password = password;

                while (true)
                {
                    readEntry = readStream.GetNextEntry();
                    if (readEntry == null)
                    {
                        break;
                    }

                    //break;
                }

                readStream.Close();
                readStream.Dispose();
                readStream = null;
            }
            catch (Exception)
            {
                return false;
            }

            return true;
        }

        public static bool CreateSingle(string filename, string password, string entryFilename, string content)
        {
            int size = 2048;
            byte[] buffer = new byte[size];
            int bufferSize = 0;

            try
            {
                ZipOutputStream zipStream = new ZipOutputStream(File.Create(filename));
                zipStream.SetLevel(9);
                zipStream.Password = password;

                // stream
                MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(content));
                ms.Position = 0;

                // write file entry
                zipStream.PutNextEntry(new ZipEntry(entryFilename));

                buffer = new byte[size];
                bufferSize = 0;

                do
                {
                    bufferSize = ms.Read(buffer, 0, buffer.Length);
                    zipStream.Write(buffer, 0, bufferSize);
                }
                while (bufferSize > 0);

                ms.Flush();
                ms.Close();
                ms.Dispose();
                ms = null;

                zipStream.Finish();
                zipStream.Flush();
                zipStream.Close();
                zipStream.Dispose();
                zipStream = null;
            }
            catch (Exception)
            {
                return false;
            }

            return true;
        }

    }
}