/**
 * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
 */

package org.onosproject.xran.codecs.pdu;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.onosproject.xran.codecs.api.CRNTI;
import org.onosproject.xran.codecs.api.ECGI;
import org.onosproject.xran.codecs.api.ENBUES1APID;
import org.onosproject.xran.codecs.api.MMEUES1APID;
import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
import org.onosproject.xran.codecs.ber.BerLength;
import org.onosproject.xran.codecs.ber.BerTag;
import org.onosproject.xran.codecs.ber.types.string.BerUTF8String;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;

public class UEContextUpdate implements Serializable {

		private static final long serialVersionUID = 1L;

		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);

		@JsonIgnore
		public byte[] code = null;
		private CRNTI crnti = null;
		private ECGI ecgi = null;
		private MMEUES1APID mMEUES1APID = null;
		private ENBUES1APID eNBUES1APID = null;
		private BerUTF8String imsi = null;

		public UEContextUpdate() {
		}

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

		public void setCrnti(CRNTI crnti) {
			this.crnti = crnti;
		}

		public CRNTI getCrnti() {
			return crnti;
		}

		public void setEcgi(ECGI ecgi) {
			this.ecgi = ecgi;
		}

		public ECGI getEcgi() {
			return ecgi;
		}

		public void setMMEUES1APID(MMEUES1APID mMEUES1APID) {
			this.mMEUES1APID = mMEUES1APID;
		}

		public MMEUES1APID getMMEUES1APID() {
			return mMEUES1APID;
		}

		public void setENBUES1APID(ENBUES1APID eNBUES1APID) {
			this.eNBUES1APID = eNBUES1APID;
		}

		public ENBUES1APID getENBUES1APID() {
			return eNBUES1APID;
		}

		public void setImsi(BerUTF8String imsi) {
			this.imsi = imsi;
		}

		public BerUTF8String getImsi() {
			return imsi;
		}

		public int encode(BerByteArrayOutputStream os) throws IOException {
			return encode(os, true);
		}

		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {

			if (code != null) {
				for (int i = code.length - 1; i >= 0; i--) {
					os.write(code[i]);
				}
				if (withTag) {
					return tag.encode(os) + code.length;
				}
				return code.length;
			}

			int codeLength = 0;
			if (imsi != null) {
				codeLength += imsi.encode(os, false);
				// write tag: CONTEXT_CLASS, PRIMITIVE, 4
				os.write(0x84);
				codeLength += 1;
			}

			codeLength += eNBUES1APID.encode(os, false);
			// write tag: CONTEXT_CLASS, PRIMITIVE, 3
			os.write(0x83);
			codeLength += 1;

			codeLength += mMEUES1APID.encode(os, false);
			// write tag: CONTEXT_CLASS, PRIMITIVE, 2
			os.write(0x82);
			codeLength += 1;

			codeLength += ecgi.encode(os, false);
			// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
			os.write(0xA1);
			codeLength += 1;

			codeLength += crnti.encode(os, false);
			// write tag: CONTEXT_CLASS, PRIMITIVE, 0
			os.write(0x80);
			codeLength += 1;

			codeLength += BerLength.encodeLength(os, codeLength);

			if (withTag) {
				codeLength += tag.encode(os);
			}

			return codeLength;

		}

		public int decode(InputStream is) throws IOException {
			return decode(is, true);
		}

		public int decode(InputStream is, boolean withTag) throws IOException {
			int codeLength = 0;
			int subCodeLength = 0;
			BerTag berTag = new BerTag();

			if (withTag) {
				codeLength += tag.decodeAndCheck(is);
			}

			BerLength length = new BerLength();
			codeLength += length.decode(is);

			int totalLength = length.val;
			codeLength += totalLength;

			subCodeLength += berTag.decode(is);
			if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
				crnti = new CRNTI();
				subCodeLength += crnti.decode(is, false);
				subCodeLength += berTag.decode(is);
			}
			else {
				throw new IOException("Tag does not match the mandatory sequence element tag.");
			}

			if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
				ecgi = new ECGI();
				subCodeLength += ecgi.decode(is, false);
				subCodeLength += berTag.decode(is);
			}
			else {
				throw new IOException("Tag does not match the mandatory sequence element tag.");
			}

			if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
				mMEUES1APID = new MMEUES1APID();
				subCodeLength += mMEUES1APID.decode(is, false);
				subCodeLength += berTag.decode(is);
			}
			else {
				throw new IOException("Tag does not match the mandatory sequence element tag.");
			}

			if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
				eNBUES1APID = new ENBUES1APID();
				subCodeLength += eNBUES1APID.decode(is, false);
				if (subCodeLength == totalLength) {
					return codeLength;
				}
				subCodeLength += berTag.decode(is);
			}
			else {
				throw new IOException("Tag does not match the mandatory sequence element tag.");
			}

			if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
				imsi = new BerUTF8String();
				subCodeLength += imsi.decode(is, false);
				if (subCodeLength == totalLength) {
					return codeLength;
				}
			}
			throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);


		}

		public void encodeAndSave(int encodingSizeGuess) throws IOException {
			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
			encode(os, false);
			code = os.getArray();
		}

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

		public void appendAsString(StringBuilder sb, int indentLevel) {

			sb.append("{");
			sb.append("\n");
			for (int i = 0; i < indentLevel + 1; i++) {
				sb.append("\t");
			}
			if (crnti != null) {
				sb.append("crnti: ").append(crnti);
			}
			else {
				sb.append("crnti: <empty-required-field>");
			}

			sb.append(",\n");
			for (int i = 0; i < indentLevel + 1; i++) {
				sb.append("\t");
			}
			if (ecgi != null) {
				sb.append("ecgi: ");
				ecgi.appendAsString(sb, indentLevel + 1);
			}
			else {
				sb.append("ecgi: <empty-required-field>");
			}

			sb.append(",\n");
			for (int i = 0; i < indentLevel + 1; i++) {
				sb.append("\t");
			}
			if (mMEUES1APID != null) {
				sb.append("mMEUES1APID: ").append(mMEUES1APID);
			}
			else {
				sb.append("mMEUES1APID: <empty-required-field>");
			}

			sb.append(",\n");
			for (int i = 0; i < indentLevel + 1; i++) {
				sb.append("\t");
			}
			if (eNBUES1APID != null) {
				sb.append("eNBUES1APID: ").append(eNBUES1APID);
			}
			else {
				sb.append("eNBUES1APID: <empty-required-field>");
			}

			if (imsi != null) {
				sb.append(",\n");
				for (int i = 0; i < indentLevel + 1; i++) {
					sb.append("\t");
				}
				sb.append("imsi: ").append(imsi);
			}

			sb.append("\n");
			for (int i = 0; i < indentLevel; i++) {
				sb.append("\t");
			}
			sb.append("}");
		}
}

