/*
 *  Copyright (C) 2020 Savoir-faire Linux Inc.
 *
 *  Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */

#ifndef MEDIASTREAM_H
#define MEDIASTREAM_H

#include <media/libav_deps.h>
#include <rational.h>

#include "audioFormat.h"

#include <string>

namespace jami {

struct MediaStream
{
    std::string name {};
    int format {-1};
    bool isVideo {false};
    rational<int> timeBase;
    int64_t firstTimestamp {0};
    int width {0};
    int height {0};
    int bitrate;
    rational<int> frameRate;
    int sampleRate {0};
    int nbChannels {0};
    int frameSize {0};

    MediaStream() {}

    MediaStream(const std::string& streamName,
                int fmt,
                rational<int> tb,
                int w,
                int h,
                int br,
                rational<int> fr)
        : name(streamName)
        , format(fmt)
        , isVideo(true)
        , timeBase(tb)
        , width(w)
        , height(h)
        , bitrate(br)
        , frameRate(fr)
    {}

    MediaStream(
        const std::string& streamName, int fmt, rational<int> tb, int sr, int channels, int size)
        : name(streamName)
        , format(fmt)
        , isVideo(false)
        , timeBase(tb)
        , sampleRate(sr)
        , nbChannels(channels)
        , frameSize(size)
    {}

    MediaStream(const std::string& streamName, AudioFormat fmt)
        : MediaStream(streamName, fmt, 0)
    {}

    MediaStream(const std::string& streamName, AudioFormat fmt, int64_t startTimestamp)
        : name(streamName)
        , format(fmt.sampleFormat)
        , isVideo(false)
        , timeBase(1, fmt.sample_rate)
        , firstTimestamp(startTimestamp)
        , sampleRate(fmt.sample_rate)
        , nbChannels(fmt.nb_channels)
        , frameSize(fmt.sample_rate / 50) // standard frame size for our encoder is 20 ms
    {}

    MediaStream(const std::string& streamName, AVCodecContext* c)
        : MediaStream(streamName, c, 0)
    {}

    MediaStream(const std::string& streamName, AVCodecContext* c, int64_t startTimestamp)
        : name(streamName)
        , firstTimestamp(startTimestamp)
    {
        if (c) {
            timeBase = c->time_base;
            switch (c->codec_type) {
            case AVMEDIA_TYPE_VIDEO:
                format = c->pix_fmt;
                isVideo = true;
                width = c->width;
                height = c->height;
                bitrate = c->bit_rate;
                frameRate = c->framerate;
                break;
            case AVMEDIA_TYPE_AUDIO:
                format = c->sample_fmt;
                isVideo = false;
                sampleRate = c->sample_rate;
                nbChannels = c->channels;
                frameSize = c->frame_size;
                break;
            default:
                break;
            }
        }
    }

    MediaStream(const MediaStream& other) = default;

    bool isValid() const
    {
        if (format < 0)
            return false;
        if (isVideo)
            return width > 0 && height > 0;
        else
            return sampleRate > 0 && nbChannels > 0;
    }

    void update(AVFrame* f)
    {
        // update all info possible (AVFrame has no fps or bitrate data)
        format = f->format;
        if (isVideo) {
            width = f->width;
            height = f->height;
        } else {
            sampleRate = f->sample_rate;
            nbChannels = f->channels;
            timeBase = rational<int>(1, f->sample_rate);
            if (!frameSize)
                frameSize = f->nb_samples;
        }
    }
};

inline std::ostream&
operator<<(std::ostream& os, const MediaStream& ms)
{
    if (ms.isVideo) {
        auto formatName = av_get_pix_fmt_name(static_cast<AVPixelFormat>(ms.format));
        os << (ms.name.empty() ? "(null)" : ms.name) << ": "
           << (formatName ? formatName : "(unknown format)") << " video, " << ms.width << "x"
           << ms.height << ", " << ms.frameRate << " fps (" << ms.timeBase << ")";
        if (ms.bitrate > 0)
            os << ", " << ms.bitrate << " kb/s";
    } else {
        os << (ms.name.empty() ? "(null)" : ms.name) << ": "
           << av_get_sample_fmt_name(static_cast<AVSampleFormat>(ms.format)) << " audio, "
           << ms.nbChannels << " channel(s), " << ms.sampleRate << " Hz (" << ms.timeBase << "), "
           << ms.frameSize << " samples per frame";
    }
    if (ms.firstTimestamp > 0)
        os << ", start: " << ms.firstTimestamp;
    return os;
}
}; // namespace jami

#endif // MEDIASTREAM_H
