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

using MessagePack;
using System.Runtime.InteropServices;

namespace Post
{
    public class StructMessagepack
    {
        #region ACDSN
        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]
        public struct ACDSN
        {
            [Key(0)]
            public UInt32 high;
            [Key(1)]
            public UInt32 wrap;
            [Key(2)]
            public UInt32 base_n;
        }
        #endregion

        #region Timespec
        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]
        public struct Timespec
        {
            [Key(0)]
            public UInt64 tv_sec;
            [Key(1)]
            public UInt64 tv_nsec;
        }
        #endregion

        #region TracingRecordHeader
        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]
        public struct TracingRecordHeader
        {
            [Key(0)]
            public byte command;  // DML, DDL
            [Key(1)]
            public byte trc_record_type;         // 0x01 DELETE, 0x02 INSERT, 0x03 UPDATE, 0x07 UPDATE including PK
            [Key(2)]
            public byte capture_type;
            [Key(3)]
            public byte partition;
            [Key(4)]
            public Int32 length;
            [Key(5)]
            public Timespec timestamp;
            [Key(6)]
            public byte redo_thread_node;
            [Key(7)]
            public Int32 redo_sequence;       // RBA
            [Key(8)]
            public Int32 redo_block;         // RBA
            [Key(9)]
            public Int32 redo_offset;         // RBA
            [Key(10)]
            public UInt32 tx_index;    // Int32 -> UInt32, 200116
            [Key(11)]
            public byte tx_indicator;
            [Key(12)]
            public Int16 record_columns;
            [Key(13)]
            public byte record_continued;
            [Key(14)]
            public UInt32 record_count;
            [Key(15)]
            public Int16 definition_id;
            [Key(16)]
            public byte[] schema; // char #define LEN_SCHEMA 129
            [Key(17)]
            public byte[] object_n; // char #define LEN_OBJECT 129
        }
        #endregion

        #region TracingRecordHeaderTransaction
        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]

        public struct TracingRecordHeaderTransaction
        {
            [Key(0)]
            public TracingRecordHeader header;
            [Key(2)]
            public TracingRecordTransaction transaction;
        }
        #endregion

        #region TracingRecordTransaction
        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]
        public struct TracingRecordTransaction
        {
            [Key(0)]
            public byte[] rowid; // char #define LEN_ROWID 24
            [Key(1)]
            public ACDSN commit_dsn;
            [Key(2)]
            public byte[] tx_id; // char #define LEN_TRANSACTION_ID 20
        }
        #endregion

        #region TracingDefinition
        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]
        public struct TracingRecordDefinition
        {
            [Key(0)]
            public TracingRecordHeader header;
            [Key(1)]
            public TracingRecordDataDefinition data;
            [Key(2)]
            public TracingRecordTransaction transaction;
        }
        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]
        public class TracingRecordDataDefinition
        {
            [Key(0)]
            public TracingRecordDataDefinitionTable table_def;
            [Key(1)]
            public TracingRecordDataDefinitionColumn[] column_def;
        }
        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]
        public class TracingRecordDataDefinitionTable
        {
            [Key(0)]
            public short definition_id;
            [Key(1)]
            public short num_columns;
            [Key(2)]
            public short num_key_columns;
            [Key(3)]
            public short num_use_columns;
            [Key(4)]
            public byte[] table_name;
        }
        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]
        public class TracingRecordDataDefinitionColumn
        {
            [Key(0)]
            public UInt16 col_no;
            [Key(1)]
            public UInt16 segcol_no;
            [Key(2)]
            public UInt16 internal_no;
            [Key(3)]
            public byte[] name;
            [Key(4)]
            public byte datatype;
            [Key(5)]
            public byte sub_datatype;
            [Key(6)]
            public UInt16 native_datatype;
            [Key(7)]
            public UInt16 extern_length;
            [Key(8)]
            public UInt16 internal_length;
            [Key(9)]
            public byte is_nullable;
            [Key(10)]
            public byte is_hidden;
            [Key(11)]
            public byte key_column;
            [Key(12)]
            public UInt16 precision;
            [Key(13)]
            public UInt16 scale;
            [Key(14)]
            public UInt64 property;
            [Key(15)]
            public UInt32 character_set;
            [Key(16)]
            public byte is_lob;
        }
        #endregion

        #region tracing_record : dml record
        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]
        public struct TracingRecordDml
        {
            [Key(0)]
            public TracingRecordHeader header;
            [Key(1)]
            public TracingRecordData[] data;
            [Key(2)]
            public TracingRecordTransaction transaction;
        }

        [MessagePackObject]
        [StructLayout(LayoutKind.Sequential)]
        public struct TracingRecordData
        {
            [Key(0)]
            public Int16 colno;
            [Key(1)]
            public byte flag;                   // 0x01 BEFORE, 0x02 AFTER
            [Key(2)]
            public Int16 type;                 // 0x01 NUMERIC, 0x02 STRING, 0x03 DATE
            [Key(3)]
            public byte is_null;
            [Key(4)]
            public UInt32 length;
            [Key(5)]
            public byte[] str; //char #define LEN_MAX_REGULAR 5000
        }
        #endregion

    }
}