/*
 * Copyright (c) 2012 Clément Bœsch
 *
 * 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
 */

/**
 * @file
 * MPL2 subtitles format demuxer
 */

#include "libavutil/intreadwrite.h"

#include "avformat.h"
#include "internal.h"
#include "subtitles.h"

typedef struct {
    FFDemuxSubtitlesQueue q;
} MPL2Context;

static int mpl2_probe(const AVProbeData *p)
{
    int i;
    char c;
    int64_t start, end;
    const unsigned char *ptr = p->buf;
    const unsigned char *ptr_end = ptr + p->buf_size;

    if (AV_RB24(ptr) == 0xefbbbf)
        ptr += 3;

    for (i = 0; i < 2; i++) {
        if (sscanf(ptr, "[%"SCNd64"][%"SCNd64"]%c", &start, &end, &c) != 3 &&
            sscanf(ptr, "[%"SCNd64"][]%c",          &start,       &c) != 2)
            return 0;
        ptr += ff_subtitles_next_line(ptr);
        if (ptr >= ptr_end)
            return 0;
    }
    return AVPROBE_SCORE_MAX;
}

static int read_ts(char **line, int64_t *pts_start, int64_t *duration)
{
    char c;
    int len;
    int64_t end;

    if (sscanf(*line, "[%"SCNd64"][]%c%n",
               pts_start, &c, &len) >= 2) {
        *duration = -1;
        *line += len - 1;
        return 0;
    }
    if (sscanf(*line, "[%"SCNd64"][%"SCNd64"]%c%n",
               pts_start, &end, &c, &len) >= 3) {
        if (end < *pts_start || end - (uint64_t)*pts_start > INT64_MAX) {
            *duration = -1;
        } else
            *duration = end - *pts_start;
        *line += len - 1;
        return 0;
    }
    return -1;
}

static int mpl2_read_header(AVFormatContext *s)
{
    MPL2Context *mpl2 = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);
    int res = 0;

    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 64, 1, 10);
    st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codecpar->codec_id   = AV_CODEC_ID_MPL2;

    if (avio_rb24(s->pb) != 0xefbbbf)
        avio_seek(s->pb, -3, SEEK_CUR);

    while (!avio_feof(s->pb)) {
        char line[4096];
        char *p = line;
        const int64_t pos = avio_tell(s->pb);
        int len = ff_get_line(s->pb, line, sizeof(line));
        int64_t pts_start;
        int64_t duration;

        if (!len)
            break;

        line[strcspn(line, "\r\n")] = 0;

        if (!read_ts(&p, &pts_start, &duration)) {
            AVPacket *sub;

            sub = ff_subtitles_queue_insert(&mpl2->q, p, strlen(p), 0);
            if (!sub) {
                ff_subtitles_queue_clean(&mpl2->q);
                return AVERROR(ENOMEM);
            }
            sub->pos = pos;
            sub->pts = pts_start;
            sub->duration = duration;
        }
    }

    ff_subtitles_queue_finalize(s, &mpl2->q);
    return res;
}

static int mpl2_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    MPL2Context *mpl2 = s->priv_data;
    return ff_subtitles_queue_read_packet(&mpl2->q, pkt);
}

static int mpl2_read_seek(AVFormatContext *s, int stream_index,
                          int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
{
    MPL2Context *mpl2 = s->priv_data;
    return ff_subtitles_queue_seek(&mpl2->q, s, stream_index,
                                   min_ts, ts, max_ts, flags);
}

static int mpl2_read_close(AVFormatContext *s)
{
    MPL2Context *mpl2 = s->priv_data;
    ff_subtitles_queue_clean(&mpl2->q);
    return 0;
}

AVInputFormat ff_mpl2_demuxer = {
    .name           = "mpl2",
    .long_name      = NULL_IF_CONFIG_SMALL("MPL2 subtitles"),
    .priv_data_size = sizeof(MPL2Context),
    .read_probe     = mpl2_probe,
    .read_header    = mpl2_read_header,
    .read_packet    = mpl2_read_packet,
    .read_seek2     = mpl2_read_seek,
    .read_close     = mpl2_read_close,
    .extensions     = "txt,mpl2",
};
