/*
 * Tee output protocol
 * Copyright (c) 2016 Michael Niedermayer
 *
 * 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 "libavutil/avstring.h"
#include "libavutil/opt.h"
#include "avformat.h"
#include "avio_internal.h"
#include "tee_common.h"

typedef struct ChildContext {
    URLContext *url_context;
} ChildContext;

typedef struct TeeContext {
    const AVClass *class;
    int child_count;
    ChildContext *child;
} TeeContext;

static const AVOption tee_options[] = {
    { NULL }
};

static const AVClass tee_class = {
    .class_name = "tee",
    .item_name  = av_default_item_name,
    .option     = tee_options,
    .version    = LIBAVUTIL_VERSION_INT,
};

static const char *const child_delim = "|";

static int tee_write(URLContext *h, const unsigned char *buf, int size)
{
    TeeContext *c = h->priv_data;
    int i;
    int main_ret = size;

    for (i=0; i<c->child_count; i++) {
        int ret = ffurl_write(c->child[i].url_context, buf, size);
        if (ret < 0)
            main_ret = ret;
    }
    return main_ret;
}

static int tee_close(URLContext *h)
{
    TeeContext *c = h->priv_data;
    int i;
    int main_ret = 0;

    for (i=0; i<c->child_count; i++) {
        int ret = ffurl_closep(&c->child[i].url_context);
        if (ret < 0)
            main_ret = ret;
    }

    av_freep(&c->child);
    c->child_count = 0;
    return main_ret;
}

static int tee_open(URLContext *h, const char *filename, int flags)
{
    TeeContext *c = h->priv_data;
    int ret, i;

    av_strstart(filename, "tee:", &filename);

    if (flags & AVIO_FLAG_READ)
        return AVERROR(ENOSYS);

    while (*filename) {
        char *child_string = av_get_token(&filename, child_delim);
        char *child_name = NULL;
        void *tmp;
        AVDictionary *options = NULL;
        if (!child_string) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }

        tmp = av_realloc_array(c->child, c->child_count + 1, sizeof(*c->child));
        if (!tmp) {
            ret = AVERROR(ENOMEM);
            goto loop_fail;
        }
        c->child = tmp;
        memset(&c->child[c->child_count], 0, sizeof(c->child[c->child_count]));

        ret = ff_tee_parse_slave_options(h, child_string, &options, &child_name);
        if (ret < 0)
            goto loop_fail;

        ret = ffurl_open_whitelist(&c->child[c->child_count].url_context, child_name, flags,
                                   &h->interrupt_callback, &options,
                                   h->protocol_whitelist, h->protocol_blacklist,
                                   h);
loop_fail:
        av_freep(&child_string);
        av_dict_free(&options);
        if (ret < 0)
            goto fail;
        c->child_count++;

        if (strspn(filename, child_delim))
            filename++;
    }

    h->is_streamed = 0;
    for (i=0; i<c->child_count; i++) {
        h->is_streamed |= c->child[i].url_context->is_streamed;
    }

    return 0;
fail:
    tee_close(h);
    return ret;
}
const URLProtocol ff_tee_protocol = {
    .name                = "tee",
    .url_open            = tee_open,
    .url_write           = tee_write,
    .url_close           = tee_close,
    .priv_data_size      = sizeof(TeeContext),
    .priv_data_class     = &tee_class,
    .default_whitelist   = "crypto,file,http,https,httpproxy,rtmp,tcp,tls"
};
