using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;

namespace OBJ_FileBus
{
    /// <summary>
    /// Order:readinfo
    /// Param:FileOptMessageArgs
    /// Ret:ReadInfoRetMessageArgs
    /// 
    /// Order:read
    /// Param:ReadParamMessageArgs
    /// Ret:ReadRetMessageArgs
    /// 
    /// Order:write
    /// Param:WriteParamMessageArgs
    /// Ret:WriteRetMessageArgs
    /// 
    /// Order:addpush
    /// Param:PushParamMessageArgs
    /// Ret:RetMessageArgs
    /// 
    /// Order:rmpush
    /// Param:PushParamMessageArgs
    /// Ret:RetMessageArgs
    /// 
    /// Order:rm
    /// Param:FileOptMessageArgs
    /// Ret:RetMessageArgs
    /// 
    /// Order:push
    /// Param:PushMessageArgs
    /// </summary>
          public enum ERRNO {
              /// <summary>
              /// 操作完成
              /// </summary>
            OK=0,
              /// <summary>
              /// 不存在
              /// </summary>
            NOEXIST=1,
              /// <summary>
              /// 需要多个包，多次读或写
              /// </summary>
            DOING=2,
              /// <summary>
              /// 异常，写入失败，或 guid 错误
              /// </summary>
            ERROR=3,
              /// <summary>
              /// 推送
              /// </summary>
            PUSH=255,
              /// <summary>
              /// 连接失败
              /// </summary>
            NOCONNECT = 4
        }
    [Serializable]
    public class Message 
    {
        public string order;
        
        public MessageArgs args;

        //public static Message Bytes2Message(byte[] order_bytes)
        //{
        //    Stream fStream = new MemoryStream(order_bytes);

        //    XmlSerializer xmlFormat = new XmlSerializer(
        //        typeof(Message),
        //        new Type[] { 
        //            typeof(MessageArgs), 
        //            typeof(FileOptMessageArgs),
        //            typeof(RetMessageArgs),
        //            typeof(ReadInfoRetMessageArgs),
        //            typeof(ReadParamMessageArgs),
        //            typeof(ReadRetMessageArgs),
        //            typeof(WriteParamMessageArgs),
        //            typeof(WriteRetMessageArgs),
        //            typeof(PushParamMessageArgs),
        //            typeof(PushMessageArgs),
        //            typeof(PushRetMessageArgs)
        //        });//创建XML序列化器，需要指定对象的类型

        //    Message message = (Message)xmlFormat.Deserialize(fStream);
        //    fStream.Close();
        //    return message;
        //}
        //public byte[] ToBytes()
        //{
        //    DateTime dt1 = DateTime.Now;




        //    Stream fStream = new MemoryStream();

        //    XmlSerializer xmlFormat = new XmlSerializer(
        //        typeof(Message),
        //        new Type[] { 
        //            typeof(MessageArgs), 
        //            typeof(FileOptMessageArgs),
        //            typeof(RetMessageArgs),
        //            typeof(ReadInfoRetMessageArgs),
        //            typeof(ReadParamMessageArgs),
        //            typeof(ReadRetMessageArgs),
        //            typeof(WriteParamMessageArgs),
        //            typeof(WriteRetMessageArgs),
        //            typeof(PushParamMessageArgs),
        //            typeof(PushMessageArgs),
        //            typeof(PushRetMessageArgs)
        //        });//创建XML序列化器，需要指定对象的类型
        //    xmlFormat.Serialize(fStream, this);
        //    DateTime dt11 = DateTime.Now;
        //    byte[] buf = new byte[fStream.Length];
        //    fStream.Seek(0, SeekOrigin.Begin);
        //    fStream.Read(buf, 0, (int)fStream.Length);
        //    fStream.Close();
        //    DateTime dt2 = DateTime.Now;
        //    TimeSpan ts = dt2 - dt_last;
        //    dt_last = dt2;

        //    TimeSpan ts2_1 = dt2 - dt1;
        //    TimeSpan ts11_1 = dt11 - dt1;
        //    System.Diagnostics.Debug.WriteLine(ts11_1.TotalMilliseconds.ToString()+" "+ ts2_1.TotalMilliseconds.ToString()+" "+ts.TotalMilliseconds.ToString() + " len=" + buf.Length.ToString());
        //    return buf;
        //}


        public static Message Bytes2Message(byte[] order_bytes)
        {
            Stream fStream = new MemoryStream(order_bytes);
            IFormatter formatter = new BinaryFormatter();
            Message message = (Message)formatter.Deserialize(fStream);
            fStream.Close();
            return message;
        }
        public byte[] ToBytes()
        {
            //DateTime dt1 = DateTime.Now;




            Stream fStream = new MemoryStream();
            
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(fStream, this);

            //DateTime dt11 = DateTime.Now;
            byte[] buf = new byte[fStream.Length];
            fStream.Seek(0, SeekOrigin.Begin);
            fStream.Read(buf, 0, (int)fStream.Length);
            fStream.Close();
            //DateTime dt2 = DateTime.Now;
            //TimeSpan ts = dt2 - dt_last;
            //dt_last = dt2;

            //TimeSpan ts2_1 = dt2 - dt1;
            //TimeSpan ts11_1 = dt11 - dt1;
            //System.Diagnostics.Debug.WriteLine(ts11_1.TotalMilliseconds.ToString() + " " + ts2_1.TotalMilliseconds.ToString() + " " + ts.TotalMilliseconds.ToString() + " len=" + buf.Length.ToString());
            return buf;
        }

        //static DateTime dt_last;
        static Message()
        {
          //  dt_last = DateTime.Now;
        }
    }
    [Serializable]
    public class MessageArgs 
    {
    
    }
    [Serializable]
    public class FileOptMessageArgs : MessageArgs 
    {
        /// <summary>
        /// 路径
        /// </summary>
        public string path;
    }
    [Serializable]
    public class RetMessageArgs : FileOptMessageArgs
    {
        /// <summary>
        /// 错误类型
        /// </summary>
        public ERRNO errno=ERRNO.OK;

    }
    [Serializable]
    public class ReadInfoRetMessageArgs : RetMessageArgs 
    {
        /// <summary>
        /// 文件类型
        /// </summary>
        public FileAttributes fileattr;
        /// <summary>
        /// 修改时间
        /// </summary>
        public DateTime lastwritetime;
        public DateTime createtime;
        public int size;
    }
    [Serializable]
    public class ReadParamMessageArgs : FileOptMessageArgs 
    {
        /// <summary>
        /// 包大小
        /// </summary>
        public UInt16 package_size;
        /// <summary>
        /// 需要读取的包号,文件比较小时，package_no=0
        /// </summary>
        public UInt16 package_no;
        /// <summary>
        /// 全局独一无二 标识，当文件比较大时，package_no>0, 都是用它读取数据
        /// </summary>
        public string guid;
    }
    [Serializable]
    public class ReadRetMessageArgs : RetMessageArgs 
    {
        
        /// <summary>
        /// 文件类型
        /// </summary>
        public FileAttributes fileattr;
        /// <summary>
        /// 修改时间
        /// </summary>
        public DateTime lastwritetime;
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime createtime;
        /// <summary>
        /// 全局独一无二 标识，当文件比较大时，package_no>0, 都是用它读取数据
        /// </summary>
        public string guid;
        /// <summary>
        /// 文件总大小（单次发送最大包，最大65535 byte）
        /// </summary>
        public UInt32 filesize; 
        /// <summary>
        /// 包大小
        /// </summary>
        public UInt16 package_size;
        /// <summary>
        /// 需要读取的包号,文件比较小时，package_no=0
        /// </summary>
        public UInt16 package_no;

        /// <summary>
        /// 文件内容
        /// </summary>
        public byte[] filecontent;

    }
    [Serializable]
    public class WriteParamMessageArgs : FileOptMessageArgs 
    {
        public FileAttributes fileattr;//文件类型 一定是 F
        /// <summary>
        /// 全局独一无二 标识，当文件比较大时，package_no>0, 都是用它读取数据
        /// </summary>
        public string guid;
        public UInt32 filesize;//文件总大小（单次发送最大包，最大65535 byte） 
        public UInt16 package_size;//包大小
        public UInt16 package_no;//当前包号 
        public byte[] filecontent;//文件内容       
    }
    [Serializable]
    public class WriteRetMessageArgs:RetMessageArgs
    {
        /// <summary>
        /// 文件类型
        /// </summary>
        public FileAttributes fileattr;

        /// <summary>
        /// 修改时间
        /// </summary>
        public DateTime lastwritetime = DateTime.MinValue;
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime createtime = DateTime.MinValue;

        /// <summary>
        /// 全局独一无二 标识，当文件比较大时，package_no>0, 都是用它读取数据
        /// </summary>
        public string guid;
    }
    [Serializable]
    public class PushParamMessageArgs:FileOptMessageArgs
    {

    }
    [Serializable]
    public class PushRetMessageArgs:RetMessageArgs
    {

    }
    [Serializable]
    public class PushMessageArgs:FileOptMessageArgs
    {
        /// <summary>
        /// 文件类型
        /// </summary>
        public FileAttributes fileattr;
        /// <summary>
        /// 修改时间
        /// </summary>
        public DateTime lastwritetime;
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime createtime;
        /// <summary>
        /// 大小
        /// </summary>
        public int size;
    }
}
