/*
 * AST muxer
 * Copyright (c) 2012 James Almer
 *
 * 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 "avformat.h"
#include "avio_internal.h"
#include "internal.h"
#include "ast.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"

typedef struct ASTMuxContext {
    AVClass *class;
    int64_t  size;
    int64_t  samples;
    int64_t  loopstart;
    int64_t  loopend;
    int      fbs;
} ASTMuxContext;

#define CHECK_LOOP(type) \
    if (ast->loop ## type > 0) { \
        ast->loop ## type = av_rescale_rnd(ast->loop ## type, enc->sample_rate, 1000, AV_ROUND_DOWN); \
        if (ast->loop ## type < 0 || ast->loop ## type > UINT_MAX) { \
            av_log(s, AV_LOG_ERROR, "Invalid loop" #type " value\n"); \
            return AVERROR(EINVAL);  \
        } \
    }

static int ast_write_header(AVFormatContext *s)
{
    ASTMuxContext *ast = s->priv_data;
    AVIOContext *pb = s->pb;
    AVCodecContext *enc;
    unsigned int codec_tag;

    if (s->nb_streams == 1) {
        enc = s->streams[0]->codec;
    } else {
        av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
        return AVERROR(EINVAL);
    }

    if (enc->codec_id == AV_CODEC_ID_ADPCM_AFC) {
        av_log(s, AV_LOG_ERROR, "muxing ADPCM AFC is not implemented\n");
        return AVERROR_PATCHWELCOME;
    }

    codec_tag = ff_codec_get_tag(ff_codec_ast_tags, enc->codec_id);
    if (!codec_tag) {
        av_log(s, AV_LOG_ERROR, "unsupported codec\n");
        return AVERROR(EINVAL);
    }

    if (ast->loopend > 0 && ast->loopstart >= ast->loopend) {
        av_log(s, AV_LOG_ERROR, "loopend can't be less or equal to loopstart\n");
        return AVERROR(EINVAL);
    }

    /* Convert milliseconds to samples */
    CHECK_LOOP(start)
    CHECK_LOOP(end)

    ffio_wfourcc(pb, "STRM");

    ast->size = avio_tell(pb);
    avio_wb32(pb, 0); /* File size minus header */
    avio_wb16(pb, codec_tag);
    avio_wb16(pb, 16); /* Bit depth */
    avio_wb16(pb, enc->channels);
    avio_wb16(pb, 0); /* Loop flag */
    avio_wb32(pb, enc->sample_rate);

    ast->samples = avio_tell(pb);
    avio_wb32(pb, 0); /* Number of samples */
    avio_wb32(pb, 0); /* Loopstart */
    avio_wb32(pb, 0); /* Loopend */
    avio_wb32(pb, 0); /* Size of first block */

    /* Unknown */
    avio_wb32(pb, 0);
    avio_wl32(pb, 0x7F);
    avio_wb64(pb, 0);
    avio_wb64(pb, 0);
    avio_wb32(pb, 0);

    avio_flush(pb);

    return 0;
}

static int ast_write_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIOContext *pb = s->pb;
    ASTMuxContext *ast = s->priv_data;
    AVCodecContext *enc = s->streams[0]->codec;
    int size = pkt->size / enc->channels;

    if (enc->frame_number == 1)
        ast->fbs = size;

    ffio_wfourcc(pb, "BLCK");
    avio_wb32(pb, size); /* Block size */

    /* padding */
    avio_wb64(pb, 0);
    avio_wb64(pb, 0);
    avio_wb64(pb, 0);

    avio_write(pb, pkt->data, pkt->size);

    return 0;
}

static int ast_write_trailer(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    ASTMuxContext *ast = s->priv_data;
    AVCodecContext *enc = s->streams[0]->codec;
    int64_t file_size = avio_tell(pb);
    int64_t samples = (file_size - 64 - (32 * enc->frame_number)) / enc->block_align; /* PCM_S16BE_PLANAR */

    av_log(s, AV_LOG_DEBUG, "total samples: %"PRId64"\n", samples);

    if (s->pb->seekable) {
        /* Number of samples */
        avio_seek(pb, ast->samples, SEEK_SET);
        avio_wb32(pb, samples);

        /* Loopstart if provided */
        if (ast->loopstart > 0) {
        if (ast->loopstart >= samples) {
            av_log(s, AV_LOG_WARNING, "Loopstart value is out of range and will be ignored\n");
            ast->loopstart = -1;
            avio_skip(pb, 4);
        } else
        avio_wb32(pb, ast->loopstart);
        } else
            avio_skip(pb, 4);

        /* Loopend if provided. Otherwise number of samples again */
        if (ast->loopend && ast->loopstart >= 0) {
            if (ast->loopend > samples) {
                av_log(s, AV_LOG_WARNING, "Loopend value is out of range and will be ignored\n");
                ast->loopend = samples;
            }
            avio_wb32(pb, ast->loopend);
        } else {
            avio_wb32(pb, samples);
        }

        /* Size of first block */
        avio_wb32(pb, ast->fbs);

        /* File size minus header */
        avio_seek(pb, ast->size, SEEK_SET);
        avio_wb32(pb, file_size - 64);

        /* Loop flag */
        if (ast->loopstart >= 0) {
            avio_skip(pb, 6);
            avio_wb16(pb, 0xFFFF);
        }

        avio_seek(pb, file_size, SEEK_SET);
        avio_flush(pb);
    }
    return 0;
}

#define OFFSET(obj) offsetof(ASTMuxContext, obj)
static const AVOption options[] = {
  { "loopstart", "Loopstart position in milliseconds.", OFFSET(loopstart), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
  { "loopend",   "Loopend position in milliseconds.",   OFFSET(loopend),   AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
  { NULL },
};

static const AVClass ast_muxer_class = {
    .class_name = "AST muxer",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

AVOutputFormat ff_ast_muxer = {
    .name              = "ast",
    .long_name         = NULL_IF_CONFIG_SMALL("AST (Audio Stream)"),
    .extensions        = "ast",
    .priv_data_size    = sizeof(ASTMuxContext),
    .audio_codec       = AV_CODEC_ID_PCM_S16BE_PLANAR,
    .video_codec       = AV_CODEC_ID_NONE,
    .write_header      = ast_write_header,
    .write_packet      = ast_write_packet,
    .write_trailer     = ast_write_trailer,
    .priv_class        = &ast_muxer_class,
    .codec_tag         = (const AVCodecTag* const []){ff_codec_ast_tags, 0},
};
