/*
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <string.h>

#include "config_components.h"

#include "libavutil/avassert.h"
#include "libavutil/log.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "libavutil/avstring.h"
#include "libavutil/bprint.h"

#include "bsf.h"
#include "bsf_internal.h"
#include "codec_desc.h"
#include "codec_par.h"
#include "packet_internal.h"

static av_always_inline const FFBitStreamFilter *ff_bsf(const AVBitStreamFilter *bsf)
{
    return (const FFBitStreamFilter*)bsf;
}

typedef struct FFBSFContext {
    AVBSFContext pub;
    AVPacket *buffer_pkt;
    int eof;
} FFBSFContext;

static av_always_inline FFBSFContext *ffbsfcontext(AVBSFContext *ctx)
{
    return (FFBSFContext *)ctx;
}

void av_bsf_free(AVBSFContext **pctx)
{
    AVBSFContext *ctx;
    FFBSFContext *bsfi;

    if (!pctx || !*pctx)
        return;
    ctx  = *pctx;
    bsfi = ffbsfcontext(ctx);

    if (ctx->priv_data) {
        if (ff_bsf(ctx->filter)->close)
            ff_bsf(ctx->filter)->close(ctx);
        if (ctx->filter->priv_class)
            av_opt_free(ctx->priv_data);
        av_freep(&ctx->priv_data);
    }
    av_packet_free(&bsfi->buffer_pkt);

    avcodec_parameters_free(&ctx->par_in);
    avcodec_parameters_free(&ctx->par_out);

    av_freep(pctx);
}

static void *bsf_child_next(void *obj, void *prev)
{
    AVBSFContext *ctx = obj;
    if (!prev && ctx->filter->priv_class)
        return ctx->priv_data;
    return NULL;
}

static const char *bsf_to_name(void *bsf)
{
    return ((AVBSFContext *)bsf)->filter->name;
}

static const AVClass bsf_class = {
    .class_name       = "AVBSFContext",
    .item_name        = bsf_to_name,
    .version          = LIBAVUTIL_VERSION_INT,
    .child_next       = bsf_child_next,
    .child_class_iterate = ff_bsf_child_class_iterate,
    .category         = AV_CLASS_CATEGORY_BITSTREAM_FILTER,
};

const AVClass *av_bsf_get_class(void)
{
    return &bsf_class;
}

int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
{
    AVBSFContext *ctx;
    FFBSFContext *bsfi;
    int ret;

    bsfi = av_mallocz(sizeof(*bsfi));
    if (!bsfi)
        return AVERROR(ENOMEM);
    ctx  = &bsfi->pub;

    ctx->av_class = &bsf_class;
    ctx->filter   = filter;

    ctx->par_in  = avcodec_parameters_alloc();
    ctx->par_out = avcodec_parameters_alloc();
    if (!ctx->par_in || !ctx->par_out) {
        ret = AVERROR(ENOMEM);
        goto fail;
    }
    /* allocate priv data and init private options */
    if (ff_bsf(filter)->priv_data_size) {
        ctx->priv_data = av_mallocz(ff_bsf(filter)->priv_data_size);
        if (!ctx->priv_data) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }
        if (filter->priv_class) {
            *(const AVClass **)ctx->priv_data = filter->priv_class;
            av_opt_set_defaults(ctx->priv_data);
        }
    }
    bsfi->buffer_pkt = av_packet_alloc();
    if (!bsfi->buffer_pkt) {
        ret = AVERROR(ENOMEM);
        goto fail;
    }

    *pctx = ctx;
    return 0;
fail:
    av_bsf_free(&ctx);
    return ret;
}

int av_bsf_init(AVBSFContext *ctx)
{
    int ret, i;

    /* check that the codec is supported */
    if (ctx->filter->codec_ids) {
        for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++)
            if (ctx->par_in->codec_id == ctx->filter->codec_ids[i])
                break;
        if (ctx->filter->codec_ids[i] == AV_CODEC_ID_NONE) {
            const AVCodecDescriptor *desc = avcodec_descriptor_get(ctx->par_in->codec_id);
            av_log(ctx, AV_LOG_ERROR, "Codec '%s' (%d) is not supported by the "
                   "bitstream filter '%s'. Supported codecs are: ",
                   desc ? desc->name : "unknown", ctx->par_in->codec_id, ctx->filter->name);
            for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++) {
                enum AVCodecID codec_id = ctx->filter->codec_ids[i];
                av_log(ctx, AV_LOG_ERROR, "%s (%d) ",
                       avcodec_get_name(codec_id), codec_id);
            }
            av_log(ctx, AV_LOG_ERROR, "\n");
            return AVERROR(EINVAL);
        }
    }

    /* initialize output parameters to be the same as input
     * init below might overwrite that */
    ret = avcodec_parameters_copy(ctx->par_out, ctx->par_in);
    if (ret < 0)
        return ret;

    ctx->time_base_out = ctx->time_base_in;

    if (ff_bsf(ctx->filter)->init) {
        ret = ff_bsf(ctx->filter)->init(ctx);
        if (ret < 0)
            return ret;
    }

    return 0;
}

void av_bsf_flush(AVBSFContext *ctx)
{
    FFBSFContext *const bsfi = ffbsfcontext(ctx);

    bsfi->eof = 0;

    av_packet_unref(bsfi->buffer_pkt);

    if (ff_bsf(ctx->filter)->flush)
        ff_bsf(ctx->filter)->flush(ctx);
}

int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
{
    FFBSFContext *const bsfi = ffbsfcontext(ctx);
    int ret;

    if (!pkt || AVPACKET_IS_EMPTY(pkt)) {
        if (pkt)
            av_packet_unref(pkt);
        bsfi->eof = 1;
        return 0;
    }

    if (bsfi->eof) {
        av_log(ctx, AV_LOG_ERROR, "A non-NULL packet sent after an EOF.\n");
        return AVERROR(EINVAL);
    }

    if (!AVPACKET_IS_EMPTY(bsfi->buffer_pkt))
        return AVERROR(EAGAIN);

    ret = av_packet_make_refcounted(pkt);
    if (ret < 0)
        return ret;
    av_packet_move_ref(bsfi->buffer_pkt, pkt);

    return 0;
}

int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
{
    return ff_bsf(ctx->filter)->filter(ctx, pkt);
}

int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
{
    FFBSFContext *const bsfi = ffbsfcontext(ctx);
    AVPacket *tmp_pkt;

    if (bsfi->eof)
        return AVERROR_EOF;

    if (AVPACKET_IS_EMPTY(bsfi->buffer_pkt))
        return AVERROR(EAGAIN);

    tmp_pkt = av_packet_alloc();
    if (!tmp_pkt)
        return AVERROR(ENOMEM);

    *pkt = bsfi->buffer_pkt;
    bsfi->buffer_pkt = tmp_pkt;

    return 0;
}

int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
{
    FFBSFContext *const bsfi = ffbsfcontext(ctx);

    if (bsfi->eof)
        return AVERROR_EOF;

    if (AVPACKET_IS_EMPTY(bsfi->buffer_pkt))
        return AVERROR(EAGAIN);

    av_packet_move_ref(pkt, bsfi->buffer_pkt);

    return 0;
}

typedef struct BSFListContext {
    const AVClass *class;

    AVBSFContext **bsfs;
    int nb_bsfs;

    unsigned idx;           // index of currently processed BSF

    char * item_name;
} BSFListContext;


static int bsf_list_init(AVBSFContext *bsf)
{
    BSFListContext *lst = bsf->priv_data;
    int ret, i;
    const AVCodecParameters *cod_par = bsf->par_in;
    AVRational tb = bsf->time_base_in;

    for (i = 0; i < lst->nb_bsfs; ++i) {
        ret = avcodec_parameters_copy(lst->bsfs[i]->par_in, cod_par);
        if (ret < 0)
            goto fail;

        lst->bsfs[i]->time_base_in = tb;

        ret = av_bsf_init(lst->bsfs[i]);
        if (ret < 0)
            goto fail;

        cod_par = lst->bsfs[i]->par_out;
        tb = lst->bsfs[i]->time_base_out;
    }

    bsf->time_base_out = tb;
    ret = avcodec_parameters_copy(bsf->par_out, cod_par);

fail:
    return ret;
}

static int bsf_list_filter(AVBSFContext *bsf, AVPacket *out)
{
    BSFListContext *lst = bsf->priv_data;
    int ret, eof = 0;

    if (!lst->nb_bsfs)
        return ff_bsf_get_packet_ref(bsf, out);

    while (1) {
        /* get a packet from the previous filter up the chain */
        if (lst->idx)
            ret = av_bsf_receive_packet(lst->bsfs[lst->idx-1], out);
        else
            ret = ff_bsf_get_packet_ref(bsf, out);
        if (ret == AVERROR(EAGAIN)) {
            if (!lst->idx)
                return ret;
            lst->idx--;
            continue;
        } else if (ret == AVERROR_EOF) {
            eof = 1;
        } else if (ret < 0)
            return ret;

        /* send it to the next filter down the chain */
        if (lst->idx < lst->nb_bsfs) {
            ret = av_bsf_send_packet(lst->bsfs[lst->idx], eof ? NULL : out);
            av_assert1(ret != AVERROR(EAGAIN));
            if (ret < 0) {
                av_packet_unref(out);
                return ret;
            }
            lst->idx++;
            eof = 0;
        } else if (eof) {
            return ret;
        } else {
            return 0;
        }
    }
}

static void bsf_list_flush(AVBSFContext *bsf)
{
    BSFListContext *lst = bsf->priv_data;

    for (int i = 0; i < lst->nb_bsfs; i++)
        av_bsf_flush(lst->bsfs[i]);
    lst->idx = 0;
}

static void bsf_list_close(AVBSFContext *bsf)
{
    BSFListContext *lst = bsf->priv_data;
    int i;

    for (i = 0; i < lst->nb_bsfs; ++i)
        av_bsf_free(&lst->bsfs[i]);
    av_freep(&lst->bsfs);
    av_freep(&lst->item_name);
}

static const char *bsf_list_item_name(void *ctx)
{
    static const char *null_filter_name = "null";
    AVBSFContext *bsf_ctx = ctx;
    BSFListContext *lst = bsf_ctx->priv_data;

    if (!lst->nb_bsfs)
        return null_filter_name;

    if (!lst->item_name) {
        int i;
        AVBPrint bp;
        av_bprint_init(&bp, 16, 128);

        av_bprintf(&bp, "bsf_list(");
        for (i = 0; i < lst->nb_bsfs; i++)
            av_bprintf(&bp, i ? ",%s" : "%s", lst->bsfs[i]->filter->name);
        av_bprintf(&bp, ")");

        av_bprint_finalize(&bp, &lst->item_name);
    }

    return lst->item_name;
}

static const AVClass bsf_list_class = {
        .class_name = "bsf_list",
        .item_name  = bsf_list_item_name,
        .version    = LIBAVUTIL_VERSION_INT,
};

static const FFBitStreamFilter list_bsf = {
        .p.name         = "bsf_list",
        .p.priv_class   = &bsf_list_class,
        .priv_data_size = sizeof(BSFListContext),
        .init           = bsf_list_init,
        .filter         = bsf_list_filter,
        .flush          = bsf_list_flush,
        .close          = bsf_list_close,
};

struct AVBSFList {
    AVBSFContext **bsfs;
    int nb_bsfs;
};

AVBSFList *av_bsf_list_alloc(void)
{
    return av_mallocz(sizeof(AVBSFList));
}

void av_bsf_list_free(AVBSFList **lst)
{
    int i;

    if (!*lst)
        return;

    for (i = 0; i < (*lst)->nb_bsfs; ++i)
        av_bsf_free(&(*lst)->bsfs[i]);
    av_free((*lst)->bsfs);
    av_freep(lst);
}

int av_bsf_list_append(AVBSFList *lst, AVBSFContext *bsf)
{
    return av_dynarray_add_nofree(&lst->bsfs, &lst->nb_bsfs, bsf);
}

static int bsf_list_append_internal(AVBSFList *lst, const char *bsf_name, const char *options, AVDictionary ** options_dict)
{
    int ret;
    const AVBitStreamFilter *filter;
    AVBSFContext *bsf;

    filter = av_bsf_get_by_name(bsf_name);
    if (!filter)
        return AVERROR_BSF_NOT_FOUND;

    ret = av_bsf_alloc(filter, &bsf);
    if (ret < 0)
        return ret;

    if (options && filter->priv_class) {
        const AVOption *opt = av_opt_next(bsf->priv_data, NULL);
        const char * shorthand[2] = {NULL};

        if (opt)
            shorthand[0] = opt->name;

        ret = av_opt_set_from_string(bsf->priv_data, options, shorthand, "=", ":");
        if (ret < 0)
            goto end;
    }

    if (options_dict) {
        ret = av_opt_set_dict2(bsf, options_dict, AV_OPT_SEARCH_CHILDREN);
        if (ret < 0)
            goto end;
    }

    ret = av_bsf_list_append(lst, bsf);

end:
    if (ret < 0)
        av_bsf_free(&bsf);

    return ret;
}

int av_bsf_list_append2(AVBSFList *lst, const char *bsf_name, AVDictionary ** options)
{
    return bsf_list_append_internal(lst, bsf_name, NULL, options);
}

int av_bsf_list_finalize(AVBSFList **lst, AVBSFContext **bsf)
{
    int ret = 0;
    BSFListContext *ctx;

    if ((*lst)->nb_bsfs == 1) {
        *bsf = (*lst)->bsfs[0];
        av_freep(&(*lst)->bsfs);
        (*lst)->nb_bsfs = 0;
        goto end;
    }

    ret = av_bsf_alloc(&list_bsf.p, bsf);
    if (ret < 0)
        return ret;

    ctx = (*bsf)->priv_data;

    ctx->bsfs = (*lst)->bsfs;
    ctx->nb_bsfs = (*lst)->nb_bsfs;

end:
    av_freep(lst);
    return ret;
}

static int bsf_parse_single(char *str, AVBSFList *bsf_lst)
{
    char *bsf_name, *bsf_options_str;

    bsf_name = av_strtok(str, "=", &bsf_options_str);
    if (!bsf_name)
        return AVERROR(EINVAL);

    return bsf_list_append_internal(bsf_lst, bsf_name, bsf_options_str, NULL);
}

int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf_lst)
{
    AVBSFList *lst;
    int ret;

    if (!str)
        return av_bsf_get_null_filter(bsf_lst);

    lst = av_bsf_list_alloc();
    if (!lst)
        return AVERROR(ENOMEM);

    do {
        char *bsf_str = av_get_token(&str, ",");
        ret = bsf_parse_single(bsf_str, lst);
        av_free(bsf_str);
        if (ret < 0)
            goto end;
    } while (*str && *++str);

    ret = av_bsf_list_finalize(&lst, bsf_lst);
end:
    if (ret < 0)
        av_bsf_list_free(&lst);
    return ret;
}

int av_bsf_get_null_filter(AVBSFContext **bsf)
{
#if CONFIG_NULL_BSF
    extern const FFBitStreamFilter ff_null_bsf;
    return av_bsf_alloc(&ff_null_bsf.p, bsf);
#else
    return av_bsf_alloc(&list_bsf.p, bsf);
#endif
}
