#include <osmocom/core/msgb.h>
#include <osmocom/core/utils.h>

#include <unistd.h>
#include <errno.h>
#include <string.h>

#include "asn1helpers.h"

#include "hnbgw.h"
#include "hnbgw_rua.h"
//#include "ranap_common.h"

#include "ranap/RANAP_RANAP-PDU.h"
#include "ranap/RANAP_ResetAcknowledge.h"
#include "ranap/RANAP_Reset.h"
#include "ranap/RANAP_ProtocolIE-ID.h"
#include "ranap/RANAP_Cause.h"
#include "ranap/RANAP_CN-DomainIndicator.h"
#include "ranap/RANAP_GlobalRNC-ID.h"
#include "ranap/RANAP_CriticalityDiagnostics.h"

/***********************************************************************
 * BEGIN auto-generated copy+pasted
 ***********************************************************************/

/* this is copy+pasted from the asn1tostruct generated code that doesn't
 * compile as a whole */

#define RANAP_DEBUG(x, args ...) DEBUGP(0, x, ## args)

extern int asn1_xer_print;

struct msgb *ranap_generate_successful_outcome(
					   e_RANAP_ProcedureCode procedureCode,
					   RANAP_Criticality_t criticality,
					   asn_TYPE_descriptor_t * td,
					   void *sptr);

RANAP_IE_t *ranap_new_ie(RANAP_ProtocolIE_ID_t id, RANAP_Criticality_t criticality,
			 asn_TYPE_descriptor_t *type, void *sptr);

#define RESETIES_RANAP_GLOBALRNC_ID_PRESENT (1 << 0)

typedef struct RANAP_ResetIEs_s {
    uint16_t             presenceMask;
    RANAP_Cause_t        cause;
    RANAP_CN_DomainIndicator_t cN_DomainIndicator;
    RANAP_GlobalRNC_ID_t globalRNC_ID; ///< Optional field
} RANAP_ResetIEs_t;

#define RESETACKNOWLEDGEIES_RANAP_CRITICALITYDIAGNOSTICS_PRESENT (1 << 0)
#define RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT     (1 << 1)

typedef struct RANAP_ResetAcknowledgeIEs_s {
    uint16_t                 presenceMask;
    RANAP_CN_DomainIndicator_t cN_DomainIndicator;
    RANAP_CriticalityDiagnostics_t criticalityDiagnostics; ///< Optional field
    RANAP_GlobalRNC_ID_t     globalRNC_ID; ///< Optional field
} RANAP_ResetAcknowledgeIEs_t;

int ranap_decode_reseties(
    RANAP_ResetIEs_t *resetIEs,
    ANY_t *any_p) {

    RANAP_Reset_t  reset;
    RANAP_Reset_t *reset_p = &reset;
    int i, decoded = 0;
    int tempDecoded = 0;
    assert(any_p != NULL);
    assert(resetIEs != NULL);

    RANAP_DEBUG("Decoding message RANAP_ResetIEs (%s:%d)\n", __FILE__, __LINE__);

    ANY_to_type_aper(any_p, &asn_DEF_RANAP_Reset, (void**)&reset_p);

    for (i = 0; i < reset_p->reset_ies.list.count; i++) {
        RANAP_IE_t *ie_p;
        ie_p = reset_p->reset_ies.list.array[i];
        switch(ie_p->id) {
            case RANAP_ProtocolIE_ID_id_Cause:
            {
                RANAP_Cause_t  ranaP_Cause;
                RANAP_Cause_t *ranaP_Cause_p = &ranaP_Cause;
                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_Cause, (void**)&ranaP_Cause_p);
                if (tempDecoded < 0) {
                    RANAP_DEBUG("Decoding of IE cause failed\n");
                    return -1;
                }
                decoded += tempDecoded;
                if (asn1_xer_print)
                    xer_fprint(stdout, &asn_DEF_RANAP_Cause, ranaP_Cause_p);
                memcpy(&resetIEs->cause, ranaP_Cause_p, sizeof(RANAP_Cause_t));
            } break;
            case RANAP_ProtocolIE_ID_id_CN_DomainIndicator:
            {
                RANAP_CN_DomainIndicator_t  ranaP_CNDomainIndicator;
                RANAP_CN_DomainIndicator_t *ranaP_CNDomainIndicator_p = &ranaP_CNDomainIndicator;
                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_CN_DomainIndicator, (void**)&ranaP_CNDomainIndicator_p);
                if (tempDecoded < 0) {
                    RANAP_DEBUG("Decoding of IE cN_DomainIndicator failed\n");
                    return -1;
                }
                decoded += tempDecoded;
                if (asn1_xer_print)
                    xer_fprint(stdout, &asn_DEF_RANAP_CN_DomainIndicator, ranaP_CNDomainIndicator_p);
                memcpy(&resetIEs->cN_DomainIndicator, ranaP_CNDomainIndicator_p, sizeof(RANAP_CN_DomainIndicator_t));
            } break;
            /* Optional field */
            case RANAP_ProtocolIE_ID_id_GlobalRNC_ID:
            {
#if 0
                RANAP_GlobalRNC_ID_t  ranaP_GlobalRNCID;
                RANAP_GlobalRNC_ID_t *ranaP_GlobalRNCID_p = &ranaP_GlobalRNCID;
                resetIEs->presenceMask |= RESETIES_RANAP_GLOBALRNC_ID_PRESENT;
                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_GlobalRNC_ID, (void**)&ranaP_GlobalRNCID_p);
                if (tempDecoded < 0) {
                    RANAP_DEBUG("Decoding of IE globalRNC_ID failed\n");
                    return -1;
                }
                decoded += tempDecoded;
                if (asn1_xer_print)
                    xer_fprint(stdout, &asn_DEF_RANAP_GlobalRNC_ID, ranaP_GlobalRNCID_p);
                memcpy(&resetIEs->globalRNC_ID, ranaP_GlobalRNCID_p, sizeof(RANAP_GlobalRNC_ID_t));
#endif
            } break;
            default:
                RANAP_DEBUG("Unknown protocol IE id (%d) for message reseties\n", (int)ie_p->id);
                return -1;
        }
    }
    return decoded;
}

int ranap_encode_resetacknowledgeies(
    RANAP_ResetAcknowledge_t *resetAcknowledge,
    RANAP_ResetAcknowledgeIEs_t *resetAcknowledgeIEs) {

    RANAP_IE_t *ie;

    if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_CN_DomainIndicator,
                          RANAP_Criticality_reject,
                          &asn_DEF_RANAP_CN_DomainIndicator,
                          &resetAcknowledgeIEs->cN_DomainIndicator)) == NULL) {
        return -1;
    }
    ASN_SEQUENCE_ADD(&resetAcknowledge->resetAcknowledge_ies.list, ie);

    /* Optional field */
    if ((resetAcknowledgeIEs->presenceMask & RESETACKNOWLEDGEIES_RANAP_CRITICALITYDIAGNOSTICS_PRESENT)
        == RESETACKNOWLEDGEIES_RANAP_CRITICALITYDIAGNOSTICS_PRESENT) {
        if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_CriticalityDiagnostics,
                              RANAP_Criticality_ignore,
                              &asn_DEF_RANAP_CriticalityDiagnostics,
                              &resetAcknowledgeIEs->criticalityDiagnostics)) == NULL) {
            return -1;
        }
        ASN_SEQUENCE_ADD(&resetAcknowledge->resetAcknowledge_ies.list, ie);
    }

    /* Optional field */
    if ((resetAcknowledgeIEs->presenceMask & RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT)
        == RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT) {
        if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_GlobalRNC_ID,
                              RANAP_Criticality_ignore,
                              &asn_DEF_RANAP_GlobalRNC_ID,
                              &resetAcknowledgeIEs->globalRNC_ID)) == NULL) {
            return -1;
        }
        ASN_SEQUENCE_ADD(&resetAcknowledge->resetAcknowledge_ies.list, ie);
    }

    return 0;
}

#include "ranap/RANAP_InitialUE-Message.h"
#include "ranap/RANAP_CN-DomainIndicator.h"
#include "ranap/RANAP_LAI.h"
#include "ranap/RANAP_SAI.h"
#include "ranap/RANAP_NAS-PDU.h"
#include "ranap/RANAP_IuSignallingConnectionIdentifier.h"
#include "ranap/RANAP_GlobalCN-ID.h"

typedef struct RANAP_InitialUE_MessageIEs_s {
    RANAP_CN_DomainIndicator_t         cN_DomainIndicator;
    RANAP_LAI_t                        lai;
    RANAP_SAI_t                        sai;
    RANAP_NAS_PDU_t                    nas_pdu;
    RANAP_IuSignallingConnectionIdentifier_t iuSigConId;
    RANAP_GlobalRNC_ID_t               globalRNC_ID;
} RANAP_InitialUE_MessageIEs_t;

int ranap_decode_initialue_messageies(
    RANAP_InitialUE_MessageIEs_t *initialUE_MessageIEs,
    ANY_t *any_p) {

    RANAP_InitialUE_Message_t  initialUE_Message;
    RANAP_InitialUE_Message_t *initialUE_Message_p = &initialUE_Message;
    int i, decoded = 0;
    int tempDecoded = 0;
    assert(any_p != NULL);
    assert(initialUE_MessageIEs != NULL);

    RANAP_DEBUG("Decoding message RANAP_InitialUE_MessageIEs (%s:%d)\n", __FILE__, __LINE__);

    ANY_to_type_aper(any_p, &asn_DEF_RANAP_InitialUE_Message, (void**)&initialUE_Message_p);

    for (i = 0; i < initialUE_Message_p->initialUE_Message_ies.list.count; i++) {
        RANAP_IE_t *ie_p;
        ie_p = initialUE_Message_p->initialUE_Message_ies.list.array[i];
        switch(ie_p->id) {
            case RANAP_ProtocolIE_ID_id_CN_DomainIndicator:
            {
                RANAP_CN_DomainIndicator_t  ranaP_CNDomainIndicator;
                RANAP_CN_DomainIndicator_t *ranaP_CNDomainIndicator_p = &ranaP_CNDomainIndicator;
                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_CN_DomainIndicator, (void**)&ranaP_CNDomainIndicator_p);
                if (tempDecoded < 0) {
                    RANAP_DEBUG("Decoding of IE cN_DomainIndicator failed\n");
                    return -1;
                }
                decoded += tempDecoded;
                if (asn1_xer_print)
                    xer_fprint(stdout, &asn_DEF_RANAP_CN_DomainIndicator, ranaP_CNDomainIndicator_p);
                memcpy(&initialUE_MessageIEs->cN_DomainIndicator, ranaP_CNDomainIndicator_p, sizeof(RANAP_CN_DomainIndicator_t));
            } break;
            case RANAP_ProtocolIE_ID_id_LAI:
            {
                RANAP_LAI_t  ranap_lai;
                RANAP_LAI_t *ranap_lai_p = &ranap_lai;
                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_LAI, (void**)&ranap_lai_p);
                if (tempDecoded < 0) {
                    RANAP_DEBUG("Decoding of IE lai failed\n");
                    return -1;
                }
                decoded += tempDecoded;
                if (asn1_xer_print)
                    xer_fprint(stdout, &asn_DEF_RANAP_LAI, ranap_lai_p);
                memcpy(&initialUE_MessageIEs->lai, ranap_lai_p, sizeof(RANAP_LAI_t));
            } break;
            case RANAP_ProtocolIE_ID_id_SAI:
            {
                RANAP_SAI_t  ranap_sai;
                RANAP_SAI_t *ranap_sai_p = &ranap_sai;
                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_SAI, (void**)&ranap_sai_p);
                if (tempDecoded < 0) {
                    RANAP_DEBUG("Decoding of IE sai failed\n");
                    return -1;
                }
                decoded += tempDecoded;
                if (asn1_xer_print)
                    xer_fprint(stdout, &asn_DEF_RANAP_SAI, ranap_sai_p);
                memcpy(&initialUE_MessageIEs->sai, ranap_sai_p, sizeof(RANAP_SAI_t));
            } break;
            case RANAP_ProtocolIE_ID_id_NAS_PDU:
            {
                RANAP_NAS_PDU_t  ranap_naspdu;
                RANAP_NAS_PDU_t *ranap_naspdu_p = &ranap_naspdu;
                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_NAS_PDU, (void**)&ranap_naspdu_p);
                if (tempDecoded < 0) {
                    RANAP_DEBUG("Decoding of IE nas_pdu failed\n");
                    return -1;
                }
                decoded += tempDecoded;
                if (asn1_xer_print)
                    xer_fprint(stdout, &asn_DEF_RANAP_NAS_PDU, ranap_naspdu_p);
                memcpy(&initialUE_MessageIEs->nas_pdu, ranap_naspdu_p, sizeof(RANAP_NAS_PDU_t));
            } break;
            case RANAP_ProtocolIE_ID_id_IuSigConId:
            {
                RANAP_IuSignallingConnectionIdentifier_t  ranaP_IuSignallingConnectionIdentifier;
                RANAP_IuSignallingConnectionIdentifier_t *ranaP_IuSignallingConnectionIdentifier_p = &ranaP_IuSignallingConnectionIdentifier;
                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_IuSignallingConnectionIdentifier, (void**)&ranaP_IuSignallingConnectionIdentifier_p);
                if (tempDecoded < 0) {
                    RANAP_DEBUG("Decoding of IE iuSigConId failed\n");
                    return -1;
                }
                decoded += tempDecoded;
                if (asn1_xer_print)
                    xer_fprint(stdout, &asn_DEF_RANAP_IuSignallingConnectionIdentifier, ranaP_IuSignallingConnectionIdentifier_p);
                memcpy(&initialUE_MessageIEs->iuSigConId, ranaP_IuSignallingConnectionIdentifier_p, sizeof(RANAP_IuSignallingConnectionIdentifier_t));
            } break;
            case RANAP_ProtocolIE_ID_id_GlobalRNC_ID:
            {
                RANAP_GlobalRNC_ID_t  ranaP_GlobalRNCID;
                RANAP_GlobalRNC_ID_t *ranaP_GlobalRNCID_p = &ranaP_GlobalRNCID;
                tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_GlobalRNC_ID, (void**)&ranaP_GlobalRNCID_p);
                if (tempDecoded < 0) {
                    RANAP_DEBUG("Decoding of IE globalRNC_ID failed\n");
                    return -1;
                }
                decoded += tempDecoded;
                if (asn1_xer_print)
                    xer_fprint(stdout, &asn_DEF_RANAP_GlobalRNC_ID, ranaP_GlobalRNCID_p);
                memcpy(&initialUE_MessageIEs->globalRNC_ID, ranaP_GlobalRNCID_p, sizeof(RANAP_GlobalRNC_ID_t));
            } break;
            default:
                RANAP_DEBUG("Unknown protocol IE id (%d) for message initialue_messageies\n", (int)ie_p->id);
                return -1;
        }
    }
    return decoded;
}


/***********************************************************************
 * END auto-generated copy+pasted
 ***********************************************************************/

static int ranap_tx_reset_ack(struct hnb_context *hnb,
				RANAP_CN_DomainIndicator_t domain)
{
	RANAP_ResetAcknowledge_t out;
	RANAP_ResetAcknowledgeIEs_t ies;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	ies.cN_DomainIndicator = domain;

	memset(&out, 0, sizeof(out));
	rc = ranap_encode_resetacknowledgeies(&out, &ies);
	if (rc < 0) {
		LOGP(DMAIN, LOGL_ERROR, "error encoding reset ack IEs: %d\n", rc);
		return rc;
	}

	msg = ranap_generate_successful_outcome(RANAP_ProcedureCode_id_Reset,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_ResetAcknowledge,
						&out);
	if (!msg)
		return -1;

	msg->dst = hnb;

	rc = rua_tx_udt(msg);

	return rc;
}

static int ranap_rx_init_reset(struct hnb_context *hnb, ANY_t *in)
{
	RANAP_ResetIEs_t ies;
	int rc;

	rc = ranap_decode_reseties(&ies, in);
	if (rc < 0)
		return rc;

	DEBUGP(DMAIN, "RESET.req\n");

	ranap_tx_reset_ack(hnb, ies.cN_DomainIndicator);

	return 0;
}

static int ranap_rx_initiating_msg(struct hnb_context *hnb, RANAP_InitiatingMessage_t *imsg)
{
	int rc;

	switch (imsg->procedureCode) {
	case RANAP_ProcedureCode_id_Reset:
		rc = ranap_rx_init_reset(hnb, &imsg->value);
		break;
	}
}

static int _hnbgw_ranap_rx(struct hnb_context *hnb, RANAP_RANAP_PDU_t *pdu)
{
	int rc;

	switch (pdu->present) {
	case RANAP_RANAP_PDU_PR_initiatingMessage:
		rc = ranap_rx_initiating_msg(hnb, &pdu->choice.initiatingMessage);
		break;
	case RANAP_RANAP_PDU_PR_successfulOutcome:
		break;
	case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
		break;
	default:
		break;
	}
}


int hnbgw_ranap_rx(struct msgb *msg, uint8_t *data, size_t len)
{
	RANAP_RANAP_PDU_t _pdu, *pdu = &_pdu;
	asn_dec_rval_t dec_ret;
	int rc;

	memset(pdu, 0, sizeof(*pdu));
	dec_ret = aper_decode(NULL,&asn_DEF_RANAP_RANAP_PDU, (void **) &pdu,
			      data, len, 0, 0);
	if (dec_ret.code != RC_OK) {
		LOGP(DMAIN, LOGL_ERROR, "Error in RANAP ASN.1 decode\n");
		return rc;
	}

	rc = _hnbgw_ranap_rx(msg->dst, pdu);

	return rc;
}

int hnbgw_ranap_init(void)
{

}
