/**
 * 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 TAINodeLocation : TBase
{

  public int AiNodeId { get; set; }

  public TEndPoint InternalEndPoint { get; set; }

  public TAINodeLocation()
  {
  }

  public TAINodeLocation(int aiNodeId, TEndPoint internalEndPoint) : this()
  {
    this.AiNodeId = aiNodeId;
    this.InternalEndPoint = internalEndPoint;
  }

  public async global::System.Threading.Tasks.Task ReadAsync(TProtocol iprot, CancellationToken cancellationToken)
  {
    iprot.IncrementRecursionDepth();
    try
    {
      bool isset_aiNodeId = false;
      bool isset_internalEndPoint = 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.I32)
            {
              AiNodeId = await iprot.ReadI32Async(cancellationToken);
              isset_aiNodeId = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          case 2:
            if (field.Type == TType.Struct)
            {
              InternalEndPoint = new TEndPoint();
              await InternalEndPoint.ReadAsync(iprot, cancellationToken);
              isset_internalEndPoint = 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_aiNodeId)
      {
        throw new TProtocolException(TProtocolException.INVALID_DATA);
      }
      if (!isset_internalEndPoint)
      {
        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("TAINodeLocation");
      await oprot.WriteStructBeginAsync(struc, cancellationToken);
      var field = new TField();
      field.Name = "aiNodeId";
      field.Type = TType.I32;
      field.ID = 1;
      await oprot.WriteFieldBeginAsync(field, cancellationToken);
      await oprot.WriteI32Async(AiNodeId, cancellationToken);
      await oprot.WriteFieldEndAsync(cancellationToken);
      if((InternalEndPoint != null))
      {
        field.Name = "internalEndPoint";
        field.Type = TType.Struct;
        field.ID = 2;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await InternalEndPoint.WriteAsync(oprot, 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 TAINodeLocation other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return System.Object.Equals(AiNodeId, other.AiNodeId)
      && System.Object.Equals(InternalEndPoint, other.InternalEndPoint);
  }

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

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

