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

package org.onosproject.xran.asn1lib.api;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
import org.onosproject.xran.asn1lib.ber.BerLength;
import org.onosproject.xran.asn1lib.ber.BerTag;
import org.onosproject.xran.asn1lib.ber.types.BerEnum;

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


public class ReportConfig 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 ReportParams reportParams = null;
    private BerEnum triggerQuantity = null;
    private BerEnum reportQuantity = null;
    public ReportConfig() {
    }

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

    public ReportParams getReportParams() {
        return reportParams;
    }

    public void setReportParams(ReportParams reportParams) {
        this.reportParams = reportParams;
    }

    public BerEnum getTriggerQuantity() {
        return triggerQuantity;
    }

    public void setTriggerQuantity(BerEnum triggerQuantity) {
        this.triggerQuantity = triggerQuantity;
    }

    public BerEnum getReportQuantity() {
        return reportQuantity;
    }

    public void setReportQuantity(BerEnum reportQuantity) {
        this.reportQuantity = reportQuantity;
    }

    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 += reportQuantity.encode(os, false);
        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
        os.write(0x82);
        codeLength += 1;

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

        codeLength += reportParams.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)) {
            reportParams = new ReportParams();
            subCodeLength += reportParams.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, 1)) {
            triggerQuantity = new BerEnum();
            subCodeLength += triggerQuantity.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)) {
            reportQuantity = new BerEnum();
            subCodeLength += reportQuantity.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 (reportParams != null) {
            sb.append("reportParams: ");
            reportParams.appendAsString(sb, indentLevel + 1);
        } else {
            sb.append("reportParams: <empty-required-field>");
        }

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

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

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

    public static class ReportParams 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 Params params = null;
        private Hysteresis hysteresis = null;
        private TimeToTrigger timetotrigger = null;
        public ReportParams() {
        }

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

        public Params getParams() {
            return params;
        }

        public void setParams(Params params) {
            this.params = params;
        }

        public Hysteresis getHysteresis() {
            return hysteresis;
        }

        public void setHysteresis(Hysteresis hysteresis) {
            this.hysteresis = hysteresis;
        }

        public TimeToTrigger getTimetotrigger() {
            return timetotrigger;
        }

        public void setTimetotrigger(TimeToTrigger timetotrigger) {
            this.timetotrigger = timetotrigger;
        }

        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;
            int sublength;

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

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

            sublength = params.encode(os);
            codeLength += sublength;
            codeLength += BerLength.encodeLength(os, sublength);
            // 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)) {
                subCodeLength += length.decode(is);
                params = new Params();
                subCodeLength += params.decode(is, null);
                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, 1)) {
                hysteresis = new Hysteresis();
                subCodeLength += hysteresis.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)) {
                timetotrigger = new TimeToTrigger();
                subCodeLength += timetotrigger.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 (params != null) {
                sb.append("params: ");
                params.appendAsString(sb, indentLevel + 1);
            } else {
                sb.append("params: <empty-required-field>");
            }

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

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

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

        public static class Params implements Serializable {

            private static final long serialVersionUID = 1L;

            @JsonIgnore
            public byte[] code = null;
            private PerParam perParam = null;
            private A1Param a1param = null;
            private A2Param a2param = null;
            private A3Param a3param = null;
            private A4Param a4param = null;
            private A5Param a5param = null;
            private A6Param a6param = null;

            public Params() {
            }

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

            public PerParam getPerParam() {
                return perParam;
            }

            public void setPerParam(PerParam perParam) {
                this.perParam = perParam;
            }

            public A1Param getA1param() {
                return a1param;
            }

            public void setA1param(A1Param a1param) {
                this.a1param = a1param;
            }

            public A2Param getA2param() {
                return a2param;
            }

            public void setA2param(A2Param a2param) {
                this.a2param = a2param;
            }

            public A3Param getA3param() {
                return a3param;
            }

            public void setA3param(A3Param a3param) {
                this.a3param = a3param;
            }

            public A4Param getA4param() {
                return a4param;
            }

            public void setA4param(A4Param a4param) {
                this.a4param = a4param;
            }

            public A5Param getA5param() {
                return a5param;
            }

            public void setA5param(A5Param a5param) {
                this.a5param = a5param;
            }

            public A6Param getA6param() {
                return a6param;
            }

            public void setA6param(A6Param a6param) {
                this.a6param = a6param;
            }

            public int encode(BerByteArrayOutputStream os) throws IOException {

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

                int codeLength = 0;
                if (a6param != null) {
                    codeLength += a6param.encode(os, false);
                    // write tag: CONTEXT_CLASS, CONSTRUCTED, 6
                    os.write(0xA6);
                    codeLength += 1;
                    return codeLength;
                }

                if (a5param != null) {
                    codeLength += a5param.encode(os, false);
                    // write tag: CONTEXT_CLASS, CONSTRUCTED, 5
                    os.write(0xA5);
                    codeLength += 1;
                    return codeLength;
                }

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

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

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

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

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

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

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

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

                int codeLength = 0;
                BerTag passedTag = berTag;

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

                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
                    perParam = new PerParam();
                    codeLength += perParam.decode(is, false);
                    return codeLength;
                }

                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
                    a1param = new A1Param();
                    codeLength += a1param.decode(is, false);
                    return codeLength;
                }

                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
                    a2param = new A2Param();
                    codeLength += a2param.decode(is, false);
                    return codeLength;
                }

                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
                    a3param = new A3Param();
                    codeLength += a3param.decode(is, false);
                    return codeLength;
                }

                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
                    a4param = new A4Param();
                    codeLength += a4param.decode(is, false);
                    return codeLength;
                }

                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 5)) {
                    a5param = new A5Param();
                    codeLength += a5param.decode(is, false);
                    return codeLength;
                }

                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 6)) {
                    a6param = new A6Param();
                    codeLength += a6param.decode(is, false);
                    return codeLength;
                }

                if (passedTag != null) {
                    return 0;
                }

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

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

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

            public void appendAsString(StringBuilder sb, int indentLevel) {

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

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

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

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

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

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

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

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

        }

    }

}

