using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PackingPress.Common
{
    class UpgradePackageReader
    {
        private readonly List<UpgradePackage> _packages = new List<UpgradePackage>();

        public IReadOnlyList<UpgradePackage> Packages => _packages;

        public UpgradePackageReader(string filePath)
        {
            LoadPackages(filePath);
        }


        private void LoadPackages(string filePath)
        {
            try
            {
                using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    var reader = new UpgradePackageStreamReader(stream);
                    var header = reader.ReadString();
                    if (header != "VUP") return;
                    var packageCount = reader.ReadInt();
                    for (int i = 0; i < packageCount; i++)
                    {
                        var platform = (PackagePlatform)reader.ReadInt();
                        var type = (PackageType)reader.ReadInt();
                        var version = Version.Parse(reader.ReadString());
                        var description = reader.ReadString();
                        var fileData = reader.ReadBytes();
                        var fileMd5 = reader.ReadBytes();
                        _packages.Add(new UpgradePackage(platform, type, version, description, fileData, fileMd5));

                    }
                }
            }
            catch (Exception)
            {
                _packages.Clear();
            }
        }

        class UpgradePackageStreamReader
        {
            private readonly Stream _stream;

            public UpgradePackageStreamReader(Stream stream)
            {
                _stream = stream;
            }

            /// <summary>
            /// Read string from stream.
            /// </summary>
            /// <returns></returns>
            public string ReadString()
            {
                var dataLength = ReadInt();
                var data = new byte[dataLength];
                _stream.Read(data, 0, dataLength);
                return Encoding.Unicode.GetString(data, 0, data.Length);
            }

            /// <summary>
            /// Read a int32 value from the stream.
            /// </summary>
            /// <returns></returns>
            public int ReadInt()
            {
                var data = new byte[sizeof(int)];
                _stream.Read(data, 0, sizeof(int));
                return BitConverter.ToInt32(data, 0);
            }


            /// <summary>
            /// Read a byte value from the stream.
            /// </summary>
            /// <returns></returns>
            public byte ReadByte()
            {
                return (byte)(_stream.ReadByte());
            }

            /// <summary>
            /// Read a byte array from the stream.
            /// </summary>
            /// <returns></returns>
            public byte[] ReadBytes()
            {
                var size = ReadInt();
                var data = new byte[size];
                _stream.Read(data, 0, size);
                return data;
            }
        }
    }
}