/**
 * 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 TSQueryNonAlignDataSet DeepCopy()
  {
    var tmp18 = new TSQueryNonAlignDataSet();
    if((TimeList != null))
    {
      tmp18.TimeList = this.TimeList.DeepCopy();
    }
    if((ValueList != null))
    {
      tmp18.ValueList = this.ValueList.DeepCopy();
    }
    return tmp18;
  }

  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 _list19 = await iprot.ReadListBeginAsync(cancellationToken);
                TimeList = new List<byte[]>(_list19.Count);
                for(int _i20 = 0; _i20 < _list19.Count; ++_i20)
                {
                  byte[] _elem21;
                  _elem21 = await iprot.ReadBinaryAsync(cancellationToken);
                  TimeList.Add(_elem21);
                }
                await iprot.ReadListEndAsync(cancellationToken);
              }
              isset_timeList = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          case 2:
            if (field.Type == TType.List)
            {
              {
                TList _list22 = await iprot.ReadListBeginAsync(cancellationToken);
                ValueList = new List<byte[]>(_list22.Count);
                for(int _i23 = 0; _i23 < _list22.Count; ++_i23)
                {
                  byte[] _elem24;
                  _elem24 = await iprot.ReadBinaryAsync(cancellationToken);
                  ValueList.Add(_elem24);
                }
                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[] _iter25 in TimeList)
          {
            await oprot.WriteBinaryAsync(_iter25, 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[] _iter26 in ValueList)
          {
            await oprot.WriteBinaryAsync(_iter26, 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();
  }
}

