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

package org.onosproject.xran.codecs.api;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
import org.onosproject.xran.codecs.ber.BerLength;
import org.onosproject.xran.codecs.ber.BerTag;

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


public class PCIARFCN 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 PhysCellId pci = null;
    private ARFCNValue earfcnDl = null;

    public PCIARFCN() {
    }

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

    public static PCIARFCN valueOf(PhysCellId pci, ARFCNValue arfcnValue) {
        PCIARFCN pciarfcn = new PCIARFCN();
        pciarfcn.setEarfcnDl(arfcnValue);
        pciarfcn.setPci(pci);
        return pciarfcn;
    }

    public PhysCellId getPci() {
        return pci;
    }

    public void setPci(PhysCellId pci) {
        this.pci = pci;
    }

    public ARFCNValue getEarfcnDl() {
        return earfcnDl;
    }

    public void setEarfcnDl(ARFCNValue earfcnDl) {
        this.earfcnDl = earfcnDl;
    }

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

        codeLength += pci.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)) {
            pci = new PhysCellId();
            subCodeLength += pci.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)) {
            earfcnDl = new ARFCNValue();
            subCodeLength += earfcnDl.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 (pci != null) {
            sb.append("pci: ").append(pci);
        }

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

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

    @Override
    public boolean equals(Object o) {
        if (o instanceof PCIARFCN) {
            return pci.equals(((PCIARFCN) o).getPci()) && earfcnDl.equals(((PCIARFCN) o).getEarfcnDl());
        }

        return super.equals(o);
    }

    @Override
    public int hashCode() {
        int result = pci.hashCode();
        result = 31 * result + earfcnDl.hashCode();
        return result;
    }
}

