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

  public Dictionary<string, string> Configs { get; set; }

  public int NodeId { get; set; }

  public TSetConfigurationReq()
  {
  }

  public TSetConfigurationReq(Dictionary<string, string> configs, int nodeId) : this()
  {
    this.Configs = configs;
    this.NodeId = nodeId;
  }

  public async global::System.Threading.Tasks.Task ReadAsync(TProtocol iprot, CancellationToken cancellationToken)
  {
    iprot.IncrementRecursionDepth();
    try
    {
      bool isset_configs = false;
      bool isset_nodeId = 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.Map)
            {
              {
                TMap _map35 = await iprot.ReadMapBeginAsync(cancellationToken);
                Configs = new Dictionary<string, string>(_map35.Count);
                for(int _i36 = 0; _i36 < _map35.Count; ++_i36)
                {
                  string _key37;
                  string _val38;
                  _key37 = await iprot.ReadStringAsync(cancellationToken);
                  _val38 = await iprot.ReadStringAsync(cancellationToken);
                  Configs[_key37] = _val38;
                }
                await iprot.ReadMapEndAsync(cancellationToken);
              }
              isset_configs = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          case 2:
            if (field.Type == TType.I32)
            {
              NodeId = await iprot.ReadI32Async(cancellationToken);
              isset_nodeId = 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_configs)
      {
        throw new TProtocolException(TProtocolException.INVALID_DATA);
      }
      if (!isset_nodeId)
      {
        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("TSetConfigurationReq");
      await oprot.WriteStructBeginAsync(struc, cancellationToken);
      var field = new TField();
      if((Configs != null))
      {
        field.Name = "configs";
        field.Type = TType.Map;
        field.ID = 1;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteMapBeginAsync(new TMap(TType.String, TType.String, Configs.Count), cancellationToken);
          foreach (string _iter39 in Configs.Keys)
          {
            await oprot.WriteStringAsync(_iter39, cancellationToken);
            await oprot.WriteStringAsync(Configs[_iter39], cancellationToken);
          }
          await oprot.WriteMapEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
      }
      field.Name = "nodeId";
      field.Type = TType.I32;
      field.ID = 2;
      await oprot.WriteFieldBeginAsync(field, cancellationToken);
      await oprot.WriteI32Async(NodeId, 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 TSetConfigurationReq other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return TCollections.Equals(Configs, other.Configs)
      && System.Object.Equals(NodeId, other.NodeId);
  }

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

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

