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

package org.onosproject.xran.asn1lib.pdu;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonValue;
import org.onosproject.xran.asn1lib.api.CRNTI;
import org.onosproject.xran.asn1lib.api.ECGI;
import org.onosproject.xran.asn1lib.api.RXSigReport;
import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
import org.onosproject.xran.asn1lib.ber.BerLength;
import org.onosproject.xran.asn1lib.ber.BerTag;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class RXSigMeasReport implements Serializable {

    public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
    private static final long serialVersionUID = 1L;
    @JsonIgnore
    public byte[] code = null;
    private Crnti crnti = null;
    private ECGI ecgi = null;
    private CellMeasReports cellMeasReports = null;

    public RXSigMeasReport() {
    }

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

    public Crnti getCrnti() {
        return crnti;
    }

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

    public ECGI getEcgi() {
        return ecgi;
    }

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

    public CellMeasReports getCellMeasReports() {
        return cellMeasReports;
    }

    public void setCellMeasReports(CellMeasReports cellMeasReports) {
        this.cellMeasReports = cellMeasReports;
    }

    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;
        codeLength += cellMeasReports.encode(os, false);
        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
        os.write(0xA2);
        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, CONSTRUCTED, 0
        os.write(0xA0);
        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.CONSTRUCTED, 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.CONSTRUCTED, 2)) {
            cellMeasReports = new CellMeasReports();
            subCodeLength += cellMeasReports.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: ");
            crnti.appendAsString(sb, indentLevel + 1);
        } 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 (cellMeasReports != null) {
            sb.append("cellMeasReports: ");
            cellMeasReports.appendAsString(sb, indentLevel + 1);
        } else {
            sb.append("cellMeasReports: <empty-required-field>");
        }

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

    public static class Crnti implements Serializable {

        public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
        private static final long serialVersionUID = 1L;
        @JsonIgnore
        public byte[] code = null;
        private List<CRNTI> seqOf = null;

        public Crnti() {
            seqOf = new ArrayList<CRNTI>();
        }

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

        @JsonValue
        public List<CRNTI> getCRNTI() {
            if (seqOf == null) {
                seqOf = new ArrayList<CRNTI>();
            }
            return seqOf;
        }

        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;
            for (int i = (seqOf.size() - 1); i >= 0; i--) {
                codeLength += seqOf.get(i).encode(os, true);
            }

            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;
            if (withTag) {
                codeLength += tag.decodeAndCheck(is);
            }

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

            while (subCodeLength < totalLength) {
                CRNTI element = new CRNTI();
                subCodeLength += element.decode(is, true);
                seqOf.add(element);
            }
            if (subCodeLength != totalLength) {
                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);

            }
            codeLength += subCodeLength;

            return codeLength;
        }

        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("{\n");
            for (int i = 0; i < indentLevel + 1; i++) {
                sb.append("\t");
            }
            if (seqOf == null) {
                sb.append("null");
            } else {
                Iterator<CRNTI> it = seqOf.iterator();
                if (it.hasNext()) {
                    sb.append(it.next());
                    while (it.hasNext()) {
                        sb.append(",\n");
                        for (int i = 0; i < indentLevel + 1; i++) {
                            sb.append("\t");
                        }
                        sb.append(it.next());
                    }
                }
            }

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

    }

    public static class CellMeasReports implements Serializable {

        public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
        private static final long serialVersionUID = 1L;
        @JsonIgnore
        public byte[] code = null;
        private List<SEQUENCEOF> seqOf = null;

        public CellMeasReports() {
            seqOf = new ArrayList<SEQUENCEOF>();
        }

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

        @JsonValue
        public List<SEQUENCEOF> getSEQUENCEOF() {
            if (seqOf == null) {
                seqOf = new ArrayList<SEQUENCEOF>();
            }
            return seqOf;
        }

        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;
            for (int i = (seqOf.size() - 1); i >= 0; i--) {
                codeLength += seqOf.get(i).encode(os, true);
            }

            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;
            if (withTag) {
                codeLength += tag.decodeAndCheck(is);
            }

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

            while (subCodeLength < totalLength) {
                SEQUENCEOF element = new SEQUENCEOF();
                subCodeLength += element.decode(is, true);
                seqOf.add(element);
            }
            if (subCodeLength != totalLength) {
                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);

            }
            codeLength += subCodeLength;

            return codeLength;
        }

        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("{\n");
            for (int i = 0; i < indentLevel + 1; i++) {
                sb.append("\t");
            }
            if (seqOf == null) {
                sb.append("null");
            } else {
                Iterator<SEQUENCEOF> it = seqOf.iterator();
                if (it.hasNext()) {
                    it.next().appendAsString(sb, indentLevel + 1);
                    while (it.hasNext()) {
                        sb.append(",\n");
                        for (int i = 0; i < indentLevel + 1; i++) {
                            sb.append("\t");
                        }
                        it.next().appendAsString(sb, indentLevel + 1);
                    }
                }
            }

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

        public static class SEQUENCEOF implements Serializable {

            public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
            private static final long serialVersionUID = 1L;
            @JsonIgnore
            public byte[] code = null;
            private List<RXSigReport> seqOf = null;

            public SEQUENCEOF() {
                seqOf = new ArrayList<RXSigReport>();
            }

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

            @JsonValue
            public List<RXSigReport> getRXSigReport() {
                if (seqOf == null) {
                    seqOf = new ArrayList<RXSigReport>();
                }
                return seqOf;
            }

            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;
                for (int i = (seqOf.size() - 1); i >= 0; i--) {
                    codeLength += seqOf.get(i).encode(os, true);
                }

                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;
                if (withTag) {
                    codeLength += tag.decodeAndCheck(is);
                }

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

                while (subCodeLength < totalLength) {
                    RXSigReport element = new RXSigReport();
                    subCodeLength += element.decode(is, true);
                    seqOf.add(element);
                }
                if (subCodeLength != totalLength) {
                    throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);

                }
                codeLength += subCodeLength;

                return codeLength;
            }

            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("{\n");
                for (int i = 0; i < indentLevel + 1; i++) {
                    sb.append("\t");
                }
                if (seqOf == null) {
                    sb.append("null");
                } else {
                    Iterator<RXSigReport> it = seqOf.iterator();
                    if (it.hasNext()) {
                        it.next().appendAsString(sb, indentLevel + 1);
                        while (it.hasNext()) {
                            sb.append(",\n");
                            for (int i = 0; i < indentLevel + 1; i++) {
                                sb.append("\t");
                            }
                            it.next().appendAsString(sb, indentLevel + 1);
                        }
                    }
                }

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

        }

    }

}

