/*
 * This class file was automatically generated by ASN1bean (http://www.beanit.com)
 */

package com.beanit.iec61850bean.internal.mms.asn1;

import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
import com.beanit.asn1bean.ber.types.BerType;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;

public class MMSpdu implements BerType, Serializable {

  private static final long serialVersionUID = 1L;

  private byte[] code = null;
  private ConfirmedRequestPDU confirmedRequestPDU = null;
  private ConfirmedResponsePDU confirmedResponsePDU = null;
  private ConfirmedErrorPDU confirmedErrorPDU = null;
  private UnconfirmedPDU unconfirmedPDU = null;
  private RejectPDU rejectPDU = null;
  private InitiateRequestPDU initiateRequestPDU = null;
  private InitiateResponsePDU initiateResponsePDU = null;
  private InitiateErrorPDU initiateErrorPDU = null;
  private ConcludeRequestPDU concludeRequestPDU = null;

  public MMSpdu() {}

  public MMSpdu(byte[] code) {
    this.code = code;
  }

  public ConfirmedRequestPDU getConfirmedRequestPDU() {
    return confirmedRequestPDU;
  }

  public void setConfirmedRequestPDU(ConfirmedRequestPDU confirmedRequestPDU) {
    this.confirmedRequestPDU = confirmedRequestPDU;
  }

  public ConfirmedResponsePDU getConfirmedResponsePDU() {
    return confirmedResponsePDU;
  }

  public void setConfirmedResponsePDU(ConfirmedResponsePDU confirmedResponsePDU) {
    this.confirmedResponsePDU = confirmedResponsePDU;
  }

  public ConfirmedErrorPDU getConfirmedErrorPDU() {
    return confirmedErrorPDU;
  }

  public void setConfirmedErrorPDU(ConfirmedErrorPDU confirmedErrorPDU) {
    this.confirmedErrorPDU = confirmedErrorPDU;
  }

  public UnconfirmedPDU getUnconfirmedPDU() {
    return unconfirmedPDU;
  }

  public void setUnconfirmedPDU(UnconfirmedPDU unconfirmedPDU) {
    this.unconfirmedPDU = unconfirmedPDU;
  }

  public RejectPDU getRejectPDU() {
    return rejectPDU;
  }

  public void setRejectPDU(RejectPDU rejectPDU) {
    this.rejectPDU = rejectPDU;
  }

  public InitiateRequestPDU getInitiateRequestPDU() {
    return initiateRequestPDU;
  }

  public void setInitiateRequestPDU(InitiateRequestPDU initiateRequestPDU) {
    this.initiateRequestPDU = initiateRequestPDU;
  }

  public InitiateResponsePDU getInitiateResponsePDU() {
    return initiateResponsePDU;
  }

  public void setInitiateResponsePDU(InitiateResponsePDU initiateResponsePDU) {
    this.initiateResponsePDU = initiateResponsePDU;
  }

  public InitiateErrorPDU getInitiateErrorPDU() {
    return initiateErrorPDU;
  }

  public void setInitiateErrorPDU(InitiateErrorPDU initiateErrorPDU) {
    this.initiateErrorPDU = initiateErrorPDU;
  }

  public ConcludeRequestPDU getConcludeRequestPDU() {
    return concludeRequestPDU;
  }

  public void setConcludeRequestPDU(ConcludeRequestPDU concludeRequestPDU) {
    this.concludeRequestPDU = concludeRequestPDU;
  }

  @Override
  public int encode(OutputStream reverseOS) throws IOException {

    if (code != null) {
      reverseOS.write(code);
      return code.length;
    }

    int codeLength = 0;
    if (concludeRequestPDU != null) {
      codeLength += concludeRequestPDU.encode(reverseOS, false);
      // write tag: CONTEXT_CLASS, PRIMITIVE, 11
      reverseOS.write(0x8B);
      codeLength += 1;
      return codeLength;
    }

    if (initiateErrorPDU != null) {
      codeLength += initiateErrorPDU.encode(reverseOS, false);
      // write tag: CONTEXT_CLASS, CONSTRUCTED, 10
      reverseOS.write(0xAA);
      codeLength += 1;
      return codeLength;
    }

    if (initiateResponsePDU != null) {
      codeLength += initiateResponsePDU.encode(reverseOS, false);
      // write tag: CONTEXT_CLASS, CONSTRUCTED, 9
      reverseOS.write(0xA9);
      codeLength += 1;
      return codeLength;
    }

    if (initiateRequestPDU != null) {
      codeLength += initiateRequestPDU.encode(reverseOS, false);
      // write tag: CONTEXT_CLASS, CONSTRUCTED, 8
      reverseOS.write(0xA8);
      codeLength += 1;
      return codeLength;
    }

    if (rejectPDU != null) {
      codeLength += rejectPDU.encode(reverseOS, false);
      // write tag: CONTEXT_CLASS, CONSTRUCTED, 4
      reverseOS.write(0xA4);
      codeLength += 1;
      return codeLength;
    }

    if (unconfirmedPDU != null) {
      codeLength += unconfirmedPDU.encode(reverseOS, false);
      // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
      reverseOS.write(0xA3);
      codeLength += 1;
      return codeLength;
    }

    if (confirmedErrorPDU != null) {
      codeLength += confirmedErrorPDU.encode(reverseOS, false);
      // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
      reverseOS.write(0xA2);
      codeLength += 1;
      return codeLength;
    }

    if (confirmedResponsePDU != null) {
      codeLength += confirmedResponsePDU.encode(reverseOS, false);
      // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
      reverseOS.write(0xA1);
      codeLength += 1;
      return codeLength;
    }

    if (confirmedRequestPDU != null) {
      codeLength += confirmedRequestPDU.encode(reverseOS, false);
      // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
      reverseOS.write(0xA0);
      codeLength += 1;
      return codeLength;
    }

    throw new IOException("Error encoding CHOICE: No element of CHOICE was selected.");
  }

  @Override
  public int decode(InputStream is) throws IOException {
    return decode(is, null);
  }

  public int decode(InputStream is, BerTag berTag) throws IOException {

    int tlvByteCount = 0;
    boolean tagWasPassed = (berTag != null);

    if (berTag == null) {
      berTag = new BerTag();
      tlvByteCount += berTag.decode(is);
    }

    if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
      confirmedRequestPDU = new ConfirmedRequestPDU();
      tlvByteCount += confirmedRequestPDU.decode(is, false);
      return tlvByteCount;
    }

    if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
      confirmedResponsePDU = new ConfirmedResponsePDU();
      tlvByteCount += confirmedResponsePDU.decode(is, false);
      return tlvByteCount;
    }

    if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
      confirmedErrorPDU = new ConfirmedErrorPDU();
      tlvByteCount += confirmedErrorPDU.decode(is, false);
      return tlvByteCount;
    }

    if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
      unconfirmedPDU = new UnconfirmedPDU();
      tlvByteCount += unconfirmedPDU.decode(is, false);
      return tlvByteCount;
    }

    if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
      rejectPDU = new RejectPDU();
      tlvByteCount += rejectPDU.decode(is, false);
      return tlvByteCount;
    }

    if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 8)) {
      initiateRequestPDU = new InitiateRequestPDU();
      tlvByteCount += initiateRequestPDU.decode(is, false);
      return tlvByteCount;
    }

    if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 9)) {
      initiateResponsePDU = new InitiateResponsePDU();
      tlvByteCount += initiateResponsePDU.decode(is, false);
      return tlvByteCount;
    }

    if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 10)) {
      initiateErrorPDU = new InitiateErrorPDU();
      tlvByteCount += initiateErrorPDU.decode(is, false);
      return tlvByteCount;
    }

    if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 11)) {
      concludeRequestPDU = new ConcludeRequestPDU();
      tlvByteCount += concludeRequestPDU.decode(is, false);
      return tlvByteCount;
    }

    if (tagWasPassed) {
      return 0;
    }

    throw new IOException("Error decoding CHOICE: Tag " + berTag + " matched to no item.");
  }

  public void encodeAndSave(int encodingSizeGuess) throws IOException {
    ReverseByteArrayOutputStream reverseOS = new ReverseByteArrayOutputStream(encodingSizeGuess);
    encode(reverseOS);
    code = reverseOS.getArray();
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    appendAsString(sb, 0);
    return sb.toString();
  }

  public void appendAsString(StringBuilder sb, int indentLevel) {

    if (confirmedRequestPDU != null) {
      sb.append("confirmedRequestPDU: ");
      confirmedRequestPDU.appendAsString(sb, indentLevel + 1);
      return;
    }

    if (confirmedResponsePDU != null) {
      sb.append("confirmedResponsePDU: ");
      confirmedResponsePDU.appendAsString(sb, indentLevel + 1);
      return;
    }

    if (confirmedErrorPDU != null) {
      sb.append("confirmedErrorPDU: ");
      confirmedErrorPDU.appendAsString(sb, indentLevel + 1);
      return;
    }

    if (unconfirmedPDU != null) {
      sb.append("unconfirmedPDU: ");
      unconfirmedPDU.appendAsString(sb, indentLevel + 1);
      return;
    }

    if (rejectPDU != null) {
      sb.append("rejectPDU: ");
      rejectPDU.appendAsString(sb, indentLevel + 1);
      return;
    }

    if (initiateRequestPDU != null) {
      sb.append("initiateRequestPDU: ");
      initiateRequestPDU.appendAsString(sb, indentLevel + 1);
      return;
    }

    if (initiateResponsePDU != null) {
      sb.append("initiateResponsePDU: ");
      initiateResponsePDU.appendAsString(sb, indentLevel + 1);
      return;
    }

    if (initiateErrorPDU != null) {
      sb.append("initiateErrorPDU: ");
      initiateErrorPDU.appendAsString(sb, indentLevel + 1);
      return;
    }

    if (concludeRequestPDU != null) {
      sb.append("concludeRequestPDU: ").append(concludeRequestPDU);
      return;
    }

    sb.append("<none>");
  }
}
