#pragma once

#include <stdio.h>
#include <stdint.h>
#include <erl_nif.h>
#include <unifex/unifex.h>
#include <unifex/payload.h>
#include "../decoder.h"

/*
 * Declaration of native functions for module Elixir.Membrane.Element.Mad.Decoder.Native.
 * The implementation have to be provided by the user.
 */

UNIFEX_TERM create(UnifexEnv* env);
UNIFEX_TERM decode_frame(UnifexEnv* env, UnifexPayload * payload, UnifexNifState* state);

/*
 * Functions that manage lib and state lifecycle
 * Functions with 'unifex_' prefix are generated automatically,
 * the user have to implement rest of them.
 */

#define UNIFEX_MODULE "Elixir.Membrane.Element.Mad.Decoder.Native"

/**
 * Allocates the state struct. Have to be paired with 'unifex_release_state' call
 */
UnifexNifState* unifex_alloc_state(UnifexEnv* env);

/**
 * Removes a reference to the state object.
 * The state is destructed when the last reference is removed.
 * Each call to 'unifex_release_state' must correspond to a previous
 * call to 'unifex_alloc_state' or 'unifex_keep_state'.
 */
void unifex_release_state(UnifexEnv* env, UnifexNifState* state);

/**
 * Increases reference count of state object.
 * Each call has to be balanced by 'unifex_release_state' call
 */
void unifex_keep_state(UnifexEnv* env, UnifexNifState* state);

/**
 * Callback called when the state struct is destroyed. It should
 * be responsible for releasing any resources kept inside state.
 */
void handle_destroy_state(UnifexEnv* env, UnifexNifState* state);

/*
 * Callbacks for nif lifecycle hooks.
 * Have to be implemented by user.
 */

/*
 * Functions that create the defined output from Nif.
 * They are automatically generated and don't need to be implemented.
 */

UNIFEX_TERM create_result_ok(UnifexEnv* env, UnifexNifState* state);
UNIFEX_TERM decode_frame_result_ok(UnifexEnv* env, UnifexPayload * payload, long bytes_used, long sample_rate, int channels);
UNIFEX_TERM decode_frame_result_error_buflen(UnifexEnv* env);
UNIFEX_TERM decode_frame_result_error_malformed(UnifexEnv* env);
UNIFEX_TERM decode_frame_result_error_recoverable(UnifexEnv* env, int bytes_to_skip);

/*
 * Functions that send the defined messages from Nif.
 * They are automatically generated and don't need to be implemented.
 */
