/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.plc4x.java.opcua.readwrite;

import static org.apache.plc4x.java.spi.codegen.fields.FieldReaderFactory.*;
import static org.apache.plc4x.java.spi.codegen.fields.FieldWriterFactory.*;
import static org.apache.plc4x.java.spi.codegen.io.DataReaderFactory.*;
import static org.apache.plc4x.java.spi.codegen.io.DataWriterFactory.*;
import static org.apache.plc4x.java.spi.generation.StaticHelper.*;

import java.time.*;
import java.util.*;
import org.apache.plc4x.java.api.exceptions.*;
import org.apache.plc4x.java.api.value.*;
import org.apache.plc4x.java.spi.codegen.*;
import org.apache.plc4x.java.spi.codegen.fields.*;
import org.apache.plc4x.java.spi.codegen.io.*;
import org.apache.plc4x.java.spi.generation.*;

// Code generated by code-generation. DO NOT EDIT.

public class CreateSessionResponse extends ExtensionObjectDefinition implements Message {

  // Accessors for discriminator values.
  public String getIdentifier() {
    return (String) "464";
  }

  // Properties.
  protected final ExtensionObjectDefinition responseHeader;
  protected final NodeId sessionId;
  protected final NodeId authenticationToken;
  protected final double revisedSessionTimeout;
  protected final PascalByteString serverNonce;
  protected final PascalByteString serverCertificate;
  protected final int noOfServerEndpoints;
  protected final List<ExtensionObjectDefinition> serverEndpoints;
  protected final int noOfServerSoftwareCertificates;
  protected final List<ExtensionObjectDefinition> serverSoftwareCertificates;
  protected final ExtensionObjectDefinition serverSignature;
  protected final long maxRequestMessageSize;

  public CreateSessionResponse(
      ExtensionObjectDefinition responseHeader,
      NodeId sessionId,
      NodeId authenticationToken,
      double revisedSessionTimeout,
      PascalByteString serverNonce,
      PascalByteString serverCertificate,
      int noOfServerEndpoints,
      List<ExtensionObjectDefinition> serverEndpoints,
      int noOfServerSoftwareCertificates,
      List<ExtensionObjectDefinition> serverSoftwareCertificates,
      ExtensionObjectDefinition serverSignature,
      long maxRequestMessageSize) {
    super();
    this.responseHeader = responseHeader;
    this.sessionId = sessionId;
    this.authenticationToken = authenticationToken;
    this.revisedSessionTimeout = revisedSessionTimeout;
    this.serverNonce = serverNonce;
    this.serverCertificate = serverCertificate;
    this.noOfServerEndpoints = noOfServerEndpoints;
    this.serverEndpoints = serverEndpoints;
    this.noOfServerSoftwareCertificates = noOfServerSoftwareCertificates;
    this.serverSoftwareCertificates = serverSoftwareCertificates;
    this.serverSignature = serverSignature;
    this.maxRequestMessageSize = maxRequestMessageSize;
  }

  public ExtensionObjectDefinition getResponseHeader() {
    return responseHeader;
  }

  public NodeId getSessionId() {
    return sessionId;
  }

  public NodeId getAuthenticationToken() {
    return authenticationToken;
  }

  public double getRevisedSessionTimeout() {
    return revisedSessionTimeout;
  }

  public PascalByteString getServerNonce() {
    return serverNonce;
  }

  public PascalByteString getServerCertificate() {
    return serverCertificate;
  }

  public int getNoOfServerEndpoints() {
    return noOfServerEndpoints;
  }

  public List<ExtensionObjectDefinition> getServerEndpoints() {
    return serverEndpoints;
  }

  public int getNoOfServerSoftwareCertificates() {
    return noOfServerSoftwareCertificates;
  }

  public List<ExtensionObjectDefinition> getServerSoftwareCertificates() {
    return serverSoftwareCertificates;
  }

  public ExtensionObjectDefinition getServerSignature() {
    return serverSignature;
  }

  public long getMaxRequestMessageSize() {
    return maxRequestMessageSize;
  }

  @Override
  protected void serializeExtensionObjectDefinitionChild(WriteBuffer writeBuffer)
      throws SerializationException {
    PositionAware positionAware = writeBuffer;
    boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
    writeBuffer.pushContext("CreateSessionResponse");

    // Simple Field (responseHeader)
    writeSimpleField("responseHeader", responseHeader, new DataWriterComplexDefault<>(writeBuffer));

    // Simple Field (sessionId)
    writeSimpleField("sessionId", sessionId, new DataWriterComplexDefault<>(writeBuffer));

    // Simple Field (authenticationToken)
    writeSimpleField(
        "authenticationToken", authenticationToken, new DataWriterComplexDefault<>(writeBuffer));

    // Simple Field (revisedSessionTimeout)
    writeSimpleField("revisedSessionTimeout", revisedSessionTimeout, writeDouble(writeBuffer, 64));

    // Simple Field (serverNonce)
    writeSimpleField("serverNonce", serverNonce, new DataWriterComplexDefault<>(writeBuffer));

    // Simple Field (serverCertificate)
    writeSimpleField(
        "serverCertificate", serverCertificate, new DataWriterComplexDefault<>(writeBuffer));

    // Simple Field (noOfServerEndpoints)
    writeSimpleField("noOfServerEndpoints", noOfServerEndpoints, writeSignedInt(writeBuffer, 32));

    // Array Field (serverEndpoints)
    writeComplexTypeArrayField("serverEndpoints", serverEndpoints, writeBuffer);

    // Simple Field (noOfServerSoftwareCertificates)
    writeSimpleField(
        "noOfServerSoftwareCertificates",
        noOfServerSoftwareCertificates,
        writeSignedInt(writeBuffer, 32));

    // Array Field (serverSoftwareCertificates)
    writeComplexTypeArrayField(
        "serverSoftwareCertificates", serverSoftwareCertificates, writeBuffer);

    // Simple Field (serverSignature)
    writeSimpleField(
        "serverSignature", serverSignature, new DataWriterComplexDefault<>(writeBuffer));

    // Simple Field (maxRequestMessageSize)
    writeSimpleField(
        "maxRequestMessageSize", maxRequestMessageSize, writeUnsignedLong(writeBuffer, 32));

    writeBuffer.popContext("CreateSessionResponse");
  }

  @Override
  public int getLengthInBytes() {
    return (int) Math.ceil((float) getLengthInBits() / 8.0);
  }

  @Override
  public int getLengthInBits() {
    int lengthInBits = super.getLengthInBits();
    CreateSessionResponse _value = this;
    boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();

    // Simple field (responseHeader)
    lengthInBits += responseHeader.getLengthInBits();

    // Simple field (sessionId)
    lengthInBits += sessionId.getLengthInBits();

    // Simple field (authenticationToken)
    lengthInBits += authenticationToken.getLengthInBits();

    // Simple field (revisedSessionTimeout)
    lengthInBits += 64;

    // Simple field (serverNonce)
    lengthInBits += serverNonce.getLengthInBits();

    // Simple field (serverCertificate)
    lengthInBits += serverCertificate.getLengthInBits();

    // Simple field (noOfServerEndpoints)
    lengthInBits += 32;

    // Array field
    if (serverEndpoints != null) {
      int i = 0;
      for (ExtensionObjectDefinition element : serverEndpoints) {
        ThreadLocalHelper.lastItemThreadLocal.set(++i >= serverEndpoints.size());
        lengthInBits += element.getLengthInBits();
      }
    }

    // Simple field (noOfServerSoftwareCertificates)
    lengthInBits += 32;

    // Array field
    if (serverSoftwareCertificates != null) {
      int i = 0;
      for (ExtensionObjectDefinition element : serverSoftwareCertificates) {
        ThreadLocalHelper.lastItemThreadLocal.set(++i >= serverSoftwareCertificates.size());
        lengthInBits += element.getLengthInBits();
      }
    }

    // Simple field (serverSignature)
    lengthInBits += serverSignature.getLengthInBits();

    // Simple field (maxRequestMessageSize)
    lengthInBits += 32;

    return lengthInBits;
  }

  public static ExtensionObjectDefinitionBuilder staticParseExtensionObjectDefinitionBuilder(
      ReadBuffer readBuffer, String identifier) throws ParseException {
    readBuffer.pullContext("CreateSessionResponse");
    PositionAware positionAware = readBuffer;
    boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();

    ExtensionObjectDefinition responseHeader =
        readSimpleField(
            "responseHeader",
            new DataReaderComplexDefault<>(
                () -> ExtensionObjectDefinition.staticParse(readBuffer, (String) ("394")),
                readBuffer));

    NodeId sessionId =
        readSimpleField(
            "sessionId",
            new DataReaderComplexDefault<>(() -> NodeId.staticParse(readBuffer), readBuffer));

    NodeId authenticationToken =
        readSimpleField(
            "authenticationToken",
            new DataReaderComplexDefault<>(() -> NodeId.staticParse(readBuffer), readBuffer));

    double revisedSessionTimeout =
        readSimpleField("revisedSessionTimeout", readDouble(readBuffer, 64));

    PascalByteString serverNonce =
        readSimpleField(
            "serverNonce",
            new DataReaderComplexDefault<>(
                () -> PascalByteString.staticParse(readBuffer), readBuffer));

    PascalByteString serverCertificate =
        readSimpleField(
            "serverCertificate",
            new DataReaderComplexDefault<>(
                () -> PascalByteString.staticParse(readBuffer), readBuffer));

    int noOfServerEndpoints = readSimpleField("noOfServerEndpoints", readSignedInt(readBuffer, 32));

    List<ExtensionObjectDefinition> serverEndpoints =
        readCountArrayField(
            "serverEndpoints",
            new DataReaderComplexDefault<>(
                () -> ExtensionObjectDefinition.staticParse(readBuffer, (String) ("314")),
                readBuffer),
            noOfServerEndpoints);

    int noOfServerSoftwareCertificates =
        readSimpleField("noOfServerSoftwareCertificates", readSignedInt(readBuffer, 32));

    List<ExtensionObjectDefinition> serverSoftwareCertificates =
        readCountArrayField(
            "serverSoftwareCertificates",
            new DataReaderComplexDefault<>(
                () -> ExtensionObjectDefinition.staticParse(readBuffer, (String) ("346")),
                readBuffer),
            noOfServerSoftwareCertificates);

    ExtensionObjectDefinition serverSignature =
        readSimpleField(
            "serverSignature",
            new DataReaderComplexDefault<>(
                () -> ExtensionObjectDefinition.staticParse(readBuffer, (String) ("458")),
                readBuffer));

    long maxRequestMessageSize =
        readSimpleField("maxRequestMessageSize", readUnsignedLong(readBuffer, 32));

    readBuffer.closeContext("CreateSessionResponse");
    // Create the instance
    return new CreateSessionResponseBuilderImpl(
        responseHeader,
        sessionId,
        authenticationToken,
        revisedSessionTimeout,
        serverNonce,
        serverCertificate,
        noOfServerEndpoints,
        serverEndpoints,
        noOfServerSoftwareCertificates,
        serverSoftwareCertificates,
        serverSignature,
        maxRequestMessageSize);
  }

  public static class CreateSessionResponseBuilderImpl
      implements ExtensionObjectDefinition.ExtensionObjectDefinitionBuilder {
    private final ExtensionObjectDefinition responseHeader;
    private final NodeId sessionId;
    private final NodeId authenticationToken;
    private final double revisedSessionTimeout;
    private final PascalByteString serverNonce;
    private final PascalByteString serverCertificate;
    private final int noOfServerEndpoints;
    private final List<ExtensionObjectDefinition> serverEndpoints;
    private final int noOfServerSoftwareCertificates;
    private final List<ExtensionObjectDefinition> serverSoftwareCertificates;
    private final ExtensionObjectDefinition serverSignature;
    private final long maxRequestMessageSize;

    public CreateSessionResponseBuilderImpl(
        ExtensionObjectDefinition responseHeader,
        NodeId sessionId,
        NodeId authenticationToken,
        double revisedSessionTimeout,
        PascalByteString serverNonce,
        PascalByteString serverCertificate,
        int noOfServerEndpoints,
        List<ExtensionObjectDefinition> serverEndpoints,
        int noOfServerSoftwareCertificates,
        List<ExtensionObjectDefinition> serverSoftwareCertificates,
        ExtensionObjectDefinition serverSignature,
        long maxRequestMessageSize) {
      this.responseHeader = responseHeader;
      this.sessionId = sessionId;
      this.authenticationToken = authenticationToken;
      this.revisedSessionTimeout = revisedSessionTimeout;
      this.serverNonce = serverNonce;
      this.serverCertificate = serverCertificate;
      this.noOfServerEndpoints = noOfServerEndpoints;
      this.serverEndpoints = serverEndpoints;
      this.noOfServerSoftwareCertificates = noOfServerSoftwareCertificates;
      this.serverSoftwareCertificates = serverSoftwareCertificates;
      this.serverSignature = serverSignature;
      this.maxRequestMessageSize = maxRequestMessageSize;
    }

    public CreateSessionResponse build() {
      CreateSessionResponse createSessionResponse =
          new CreateSessionResponse(
              responseHeader,
              sessionId,
              authenticationToken,
              revisedSessionTimeout,
              serverNonce,
              serverCertificate,
              noOfServerEndpoints,
              serverEndpoints,
              noOfServerSoftwareCertificates,
              serverSoftwareCertificates,
              serverSignature,
              maxRequestMessageSize);
      return createSessionResponse;
    }
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof CreateSessionResponse)) {
      return false;
    }
    CreateSessionResponse that = (CreateSessionResponse) o;
    return (getResponseHeader() == that.getResponseHeader())
        && (getSessionId() == that.getSessionId())
        && (getAuthenticationToken() == that.getAuthenticationToken())
        && (getRevisedSessionTimeout() == that.getRevisedSessionTimeout())
        && (getServerNonce() == that.getServerNonce())
        && (getServerCertificate() == that.getServerCertificate())
        && (getNoOfServerEndpoints() == that.getNoOfServerEndpoints())
        && (getServerEndpoints() == that.getServerEndpoints())
        && (getNoOfServerSoftwareCertificates() == that.getNoOfServerSoftwareCertificates())
        && (getServerSoftwareCertificates() == that.getServerSoftwareCertificates())
        && (getServerSignature() == that.getServerSignature())
        && (getMaxRequestMessageSize() == that.getMaxRequestMessageSize())
        && super.equals(that)
        && true;
  }

  @Override
  public int hashCode() {
    return Objects.hash(
        super.hashCode(),
        getResponseHeader(),
        getSessionId(),
        getAuthenticationToken(),
        getRevisedSessionTimeout(),
        getServerNonce(),
        getServerCertificate(),
        getNoOfServerEndpoints(),
        getServerEndpoints(),
        getNoOfServerSoftwareCertificates(),
        getServerSoftwareCertificates(),
        getServerSignature(),
        getMaxRequestMessageSize());
  }

  @Override
  public String toString() {
    WriteBufferBoxBased writeBufferBoxBased = new WriteBufferBoxBased(true, true);
    try {
      writeBufferBoxBased.writeSerializable(this);
    } catch (SerializationException e) {
      throw new RuntimeException(e);
    }
    return "\n" + writeBufferBoxBased.getBox().toString() + "\n";
  }
}
