/**
 * Autogenerated by Thrift Compiler (0.14.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Thrift;
using Thrift.Collections;

using Thrift.Protocol;
using Thrift.Protocol.Entities;
using Thrift.Protocol.Utilities;
using Thrift.Transport;
using Thrift.Transport.Client;
using Thrift.Transport.Server;
using Thrift.Processor;


#pragma warning disable IDE0079  // remove unnecessary pragmas
#pragma warning disable IDE1006  // parts of the code use IDL spelling


public partial class TSQueryNonAlignDataSet : TBase
{

  public List<byte[]> TimeList { get; set; }

  public List<byte[]> ValueList { get; set; }

  public TSQueryNonAlignDataSet()
  {
  }

  public TSQueryNonAlignDataSet(List<byte[]> timeList, List<byte[]> valueList) : this()
  {
    this.TimeList = timeList;
    this.ValueList = valueList;
  }

  public async global::System.Threading.Tasks.Task ReadAsync(TProtocol iprot, CancellationToken cancellationToken)
  {
    iprot.IncrementRecursionDepth();
    try
    {
      bool isset_timeList = false;
      bool isset_valueList = false;
      TField field;
      await iprot.ReadStructBeginAsync(cancellationToken);
      while (true)
      {
        field = await iprot.ReadFieldBeginAsync(cancellationToken);
        if (field.Type == TType.Stop)
        {
          break;
        }

        switch (field.ID)
        {
          case 1:
            if (field.Type == TType.List)
            {
              {
                TList _list9 = await iprot.ReadListBeginAsync(cancellationToken);
                TimeList = new List<byte[]>(_list9.Count);
                for(int _i10 = 0; _i10 < _list9.Count; ++_i10)
                {
                  byte[] _elem11;
                  _elem11 = await iprot.ReadBinaryAsync(cancellationToken);
                  TimeList.Add(_elem11);
                }
                await iprot.ReadListEndAsync(cancellationToken);
              }
              isset_timeList = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          case 2:
            if (field.Type == TType.List)
            {
              {
                TList _list12 = await iprot.ReadListBeginAsync(cancellationToken);
                ValueList = new List<byte[]>(_list12.Count);
                for(int _i13 = 0; _i13 < _list12.Count; ++_i13)
                {
                  byte[] _elem14;
                  _elem14 = await iprot.ReadBinaryAsync(cancellationToken);
                  ValueList.Add(_elem14);
                }
                await iprot.ReadListEndAsync(cancellationToken);
              }
              isset_valueList = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          default: 
            await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            break;
        }

        await iprot.ReadFieldEndAsync(cancellationToken);
      }

      await iprot.ReadStructEndAsync(cancellationToken);
      if (!isset_timeList)
      {
        throw new TProtocolException(TProtocolException.INVALID_DATA);
      }
      if (!isset_valueList)
      {
        throw new TProtocolException(TProtocolException.INVALID_DATA);
      }
    }
    finally
    {
      iprot.DecrementRecursionDepth();
    }
  }

  public async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)
  {
    oprot.IncrementRecursionDepth();
    try
    {
      var struc = new TStruct("TSQueryNonAlignDataSet");
      await oprot.WriteStructBeginAsync(struc, cancellationToken);
      var field = new TField();
      if((TimeList != null))
      {
        field.Name = "timeList";
        field.Type = TType.List;
        field.ID = 1;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteListBeginAsync(new TList(TType.String, TimeList.Count), cancellationToken);
          foreach (byte[] _iter15 in TimeList)
          {
            await oprot.WriteBinaryAsync(_iter15, cancellationToken);
          }
          await oprot.WriteListEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
      }
      if((ValueList != null))
      {
        field.Name = "valueList";
        field.Type = TType.List;
        field.ID = 2;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteListBeginAsync(new TList(TType.String, ValueList.Count), cancellationToken);
          foreach (byte[] _iter16 in ValueList)
          {
            await oprot.WriteBinaryAsync(_iter16, cancellationToken);
          }
          await oprot.WriteListEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
      }
      await oprot.WriteFieldStopAsync(cancellationToken);
      await oprot.WriteStructEndAsync(cancellationToken);
    }
    finally
    {
      oprot.DecrementRecursionDepth();
    }
  }

  public override bool Equals(object that)
  {
    if (!(that is TSQueryNonAlignDataSet other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return TCollections.Equals(TimeList, other.TimeList)
      && TCollections.Equals(ValueList, other.ValueList);
  }

  public override int GetHashCode() {
    int hashcode = 157;
    unchecked {
      if((TimeList != null))
      {
        hashcode = (hashcode * 397) + TCollections.GetHashCode(TimeList);
      }
      if((ValueList != null))
      {
        hashcode = (hashcode * 397) + TCollections.GetHashCode(ValueList);
      }
    }
    return hashcode;
  }

  public override string ToString()
  {
    var sb = new StringBuilder("TSQueryNonAlignDataSet(");
    if((TimeList != null))
    {
      sb.Append(", TimeList: ");
      TimeList.ToString(sb);
    }
    if((ValueList != null))
    {
      sb.Append(", ValueList: ");
      ValueList.ToString(sb);
    }
    sb.Append(')');
    return sb.ToString();
  }
}

