/**
 * 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.BerBoolean;
import org.onosproject.xran.asn1lib.ber.types.BerEnum;
import org.onosproject.xran.asn1lib.ber.types.BerInteger;

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


public class CACap 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 BerInteger band = null;
    private BerEnum caclassdl = null;
    private BerEnum caclassul = null;
    private BerBoolean crossCarrierSched = null;

    public CACap() {
    }

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

    public BerInteger getBand() {
        return band;
    }

    public void setBand(BerInteger band) {
        this.band = band;
    }

    public BerEnum getCaclassdl() {
        return caclassdl;
    }

    public void setCaclassdl(BerEnum caclassdl) {
        this.caclassdl = caclassdl;
    }

    public BerEnum getCaclassul() {
        return caclassul;
    }

    public void setCaclassul(BerEnum caclassul) {
        this.caclassul = caclassul;
    }

    public BerBoolean getCrossCarrierSched() {
        return crossCarrierSched;
    }

    public void setCrossCarrierSched(BerBoolean crossCarrierSched) {
        this.crossCarrierSched = crossCarrierSched;
    }

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

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

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

        codeLength += band.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)) {
            band = new BerInteger();
            subCodeLength += band.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)) {
            caclassdl = new BerEnum();
            subCodeLength += caclassdl.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)) {
            caclassul = new BerEnum();
            subCodeLength += caclassul.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)) {
            crossCarrierSched = new BerBoolean();
            subCodeLength += crossCarrierSched.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 (band != null) {
            sb.append("band: ").append(band);
        } else {
            sb.append("band: <empty-required-field>");
        }

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

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

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

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

}

