/**
 *  Copyright (C) 2021 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.
 */

#include "WatermarkVideoSubscriber.h"

extern "C" {
#include <libavutil/display.h>
}
#include <accel.h>
#include <frameScaler.h>

#include <pluglog.h>
#include <algorithm>
#include <ctime>
#include <clocale>
#include <iostream>

const std::string TAG = "Watermark";
const char sep = separator();

namespace jami {

WatermarkVideoSubscriber::WatermarkVideoSubscriber(const std::string& dataPath)
{
    if (std::setlocale(LC_TIME, std::locale("").name().c_str()) == NULL) {
        Plog::log(Plog::LogPriority::INFO, TAG, "error while setting locale");
    }

    std::setlocale(LC_NUMERIC, "C");
    fontFile_ = dataPath + sep + "Muli-Light.ttf";
#ifdef WIN32
    for (int i = fontFile_.size(); i > 0; i--)
        if (fontFile_[i] == '\\')
            fontFile_.insert(i, "\\");
    fontFile_.insert(1, "\\");
#endif
}

WatermarkVideoSubscriber::~WatermarkVideoSubscriber()
{
    validLogo_ = false;
    logoFilter_.clean();
    detach();
    std::lock_guard<std::mutex> lk(mtx_);
    Plog::log(Plog::LogPriority::INFO, TAG, "~WatermarkMediaProcessor");
}

MediaStream
WatermarkVideoSubscriber::getLogoAVFrameInfos()
{
    AVFormatContext* ctx = avformat_alloc_context();

    // Open
    if (avformat_open_input(&ctx, logoPath_.c_str(), NULL, NULL) != 0) {
        avformat_free_context(ctx);
        Plog::log(Plog::LogPriority::INFO, TAG, "Couldn't open input stream.");
        return {};
    }
    pFormatCtx_.reset(ctx);
    // Retrieve stream information
    if (avformat_find_stream_info(pFormatCtx_.get(), NULL) < 0) {
        Plog::log(Plog::LogPriority::INFO, TAG, "Couldn't find stream information.");
        return {};
    }

    // Dump valid information onto standard error
    av_dump_format(pFormatCtx_.get(), 0, logoPath_.c_str(), false);

    // Find the video stream
    for (int i = 0; i < static_cast<int>(pFormatCtx_->nb_streams); i++)
        if (pFormatCtx_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStream_ = i;
            break;
        }

    if (videoStream_ == -1) {
        Plog::log(Plog::LogPriority::INFO, TAG, "Didn't find a video stream.");
        return {};
    }

    rational<int> fr = pFormatCtx_->streams[videoStream_]->r_frame_rate;
    return MediaStream("logo",
                       pFormatCtx_->streams[videoStream_]->codecpar->format,
                       1 / fr,
                       pFormatCtx_->streams[videoStream_]->codecpar->width,
                       pFormatCtx_->streams[videoStream_]->codecpar->height,
                       0,
                       fr);
}

void
WatermarkVideoSubscriber::loadMarkLogo()
{
    if (logoPath_.empty())
        return;

    logoFilter_.clean();
    logoDescription_ = "[logo]scale=" + logoSize_ + "*" + std::to_string(pluginFrameSize_.first)
                       + ":" + logoSize_ + "*" + std::to_string(pluginFrameSize_.second)
                       + ":force_original_aspect_ratio='decrease',format=yuva444p,"
                         "split=2[bg][fg],[bg]drawbox=c='"
                       + backgroundColor_
                       + "':replace=1:t=fill[bg],"
                         "[bg][fg]overlay=format=auto";
    Plog::log(Plog::LogPriority::INFO, TAG, logoDescription_);
    logoStream_ = getLogoAVFrameInfos();
    logoFilter_.initialize(logoDescription_, {logoStream_});

    int got_frame;
    AVCodecContext* pCodecCtx;
    AVPacket* packet;

    const AVCodec* pCodec = avcodec_find_decoder(
        pFormatCtx_->streams[videoStream_]->codecpar->codec_id);
    if (pCodec == nullptr) {
        pFormatCtx_.reset();
        Plog::log(Plog::LogPriority::INFO, TAG, "Codec not found.");
        validLogo_ = false;
        return;
    }

    pCodecCtx = avcodec_alloc_context3(pCodec);
    // Open codec
    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
        pFormatCtx_.reset();
        Plog::log(Plog::LogPriority::INFO, TAG, "Could not open codec.");
        validLogo_ = false;
        return;
    }

    packet = av_packet_alloc();
    if (av_read_frame(pFormatCtx_.get(), packet) < 0) {
        avcodec_close(pCodecCtx);
        av_packet_free(&packet);
        pFormatCtx_.reset();
        Plog::log(Plog::LogPriority::INFO, TAG, "Could not read packet from context.");
        validLogo_ = false;
        return;
    }

    if (avcodec_send_packet(pCodecCtx, packet) < 0) {
        avcodec_close(pCodecCtx);
        av_packet_free(&packet);
        pFormatCtx_.reset();
        Plog::log(Plog::LogPriority::INFO, TAG, "Could not send packet no codec.");
        validLogo_ = false;
        return;
    }

    AVFrame* logoImage = av_frame_alloc();
    if (avcodec_receive_frame(pCodecCtx, logoImage) < 0) {
        avcodec_close(pCodecCtx);
        av_packet_free(&packet);
        pFormatCtx_.reset();
        Plog::log(Plog::LogPriority::INFO, TAG, "Could not read packet from codec.");
        validLogo_ = false;
        return;
    }

    logoFilter_.feedInput(logoImage, "logo");
    logoFilter_.feedEOF("logo");

    frameFree(logoImage);
    avcodec_close(pCodecCtx);
    av_packet_free(&packet);
    pFormatCtx_.reset();
    mark_.reset(logoFilter_.readOutput());
    mark_->pts = 0;
    mark_->best_effort_timestamp = 0;
    validLogo_ = mark_->width && mark_->height;
}

void
WatermarkVideoSubscriber::setParameter(std::string& parameter, Parameter type)
{
    switch (type) {
    case (Parameter::LOGOSIZE):
        logoSize_ = parameter;
        break;
    case (Parameter::TIMEZONE):
        timeZone_ = parameter == "1";
        return;
    case (Parameter::FONTSIZE):
        fontSize_ = std::stoi(parameter);
        break;
    case (Parameter::LOGOBACKGROUND):
        backgroundColor_ = parameter;
        if (backgroundColor_.find("black") == std::string::npos) {
            fontColor_ = "black";
            fontBackground_ = "white@0.5";
        } else {
            fontColor_ = "white";
            fontBackground_ = "black@0.5";
        }
        if (!logoPath_.empty())
            setParameter(logoPath_, Parameter::LOGOPATH);
        break;
    case (Parameter::SHOWLOGO):
        showLogo_ = parameter == "1";
        break;
    case (Parameter::SHOWINFOS):
        showInfos_ = parameter == "1";
        break;
    case (Parameter::LOGOPATH):
        logoPath_ = parameter;
        break;
    case (Parameter::TIME):
        time_ = parameter == "1";
        break;
    case (Parameter::DATE):
        date_ = parameter == "1";
        break;
    case (Parameter::TIMEFORMAT):
        timeFormat_ = "%{localtime\\:'" + parameter + "'}";
        if (timeZone_)
            timeFormat_ = "%{localtime\\:'" + parameter + " %Z'}";
        break;
    case (Parameter::DATEFORMAT):
        dateFormat_ = "%{localtime\\:'" + parameter + "'}";
        break;
    case (Parameter::LOCATION):
        location_ = parameter;
        break;
    case (Parameter::INFOSPOSITION):
        infosposition_ = parameter;
        break;
    case (Parameter::LOGOPOSITION):
        logoposition_ = parameter;
        break;
    default:
        return;
    }

    firstRun = true;
}

void
WatermarkVideoSubscriber::setFilterDescription()
{
    loadMarkLogo();

    std::string infoSep = ", ";
    if (pluginFrameSize_.first < pluginFrameSize_.second)
        infoSep = ",\n";

    std::vector<std::string> infos;
    infosSize_ = 0;
    if (!location_.empty()) {
        infosSize_++;
        infos.emplace_back(location_);
    }
    if (date_) {
        infosSize_++;
        infos.emplace_back(dateFormat_);
    }
    if (time_) {
        infosSize_++;
        infos.emplace_back(timeFormat_);
    }
    infosString.clear();
    for (int i = 0; i < infosSize_ - 1; i++)
        infosString += infos[i] + infoSep;
    if (infosSize_ > 0)
        infosString += infos.back();

    setMarkPosition();

    std::string rotateSides = "";
    if (std::abs(angle_) == 90)
        rotateSides = ":out_w=ih:out_h=iw";

    if (angle_ != 0)
        pluginFilterDescription_ = "[input]rotate=" + rotation[angle_] + rotateSides
                                   + "[rot],[rot][mark]overlay=" + std::to_string(points_[0].first)
                                   + ":" + std::to_string(points_[0].second)
                                   + ",rotate=" + rotation[-angle_] + rotateSides;
    else
        pluginFilterDescription_ = "[input][mark]overlay=" + std::to_string(points_[0].first) + ":"
                                   + std::to_string(points_[0].second);

    std::string baseInfosDescription = "[input]rotate=" + rotation[angle_] + rotateSides
                                       + ",drawtext=fontfile='" + fontFile_ + "':text='"
                                       + infosString + "':fontcolor=" + fontColor_
                                       + ":fontsize=" + std::to_string(fontSize_)
                                       + ":line_spacing=" + std::to_string(lineSpacing_)
                                       + ":box=1:boxcolor=" + fontBackground_ + ":boxborderw=5:x=";

    if (infosposition_ == "1")
        infosDescription_ = baseInfosDescription + std::to_string(points_[1].first)
                            + "-text_w:y=" + std::to_string(points_[1].second);
    else if (infosposition_ == "2")
        infosDescription_ = baseInfosDescription + std::to_string(points_[1].first)
                            + ":y=" + std::to_string(points_[1].second);
    else if (infosposition_ == "3")
        infosDescription_ = baseInfosDescription + std::to_string(points_[1].first)
                            + ":y=" + std::to_string(points_[1].second) + "-text_h";
    else if (infosposition_ == "4")
        infosDescription_ = baseInfosDescription + std::to_string(points_[1].first)
                            + "-text_w:y=" + std::to_string(points_[1].second) + "-text_h";
    infosDescription_ += ",rotate=" + rotation[-angle_] + rotateSides + ",format=yuv420p";

    Plog::log(Plog::LogPriority::INFO, TAG, infosDescription_);
    Plog::log(Plog::LogPriority::INFO, TAG, pluginFilterDescription_);
}

void
WatermarkVideoSubscriber::setMarkPosition()
{
    // 1, 2, 3, and 4 are cartesian positions
    int margin = 10;
    int markWidth = showLogo_ ? mark_->width : 0;
    int markHeight = showLogo_ ? mark_->height : 0;
    int infoHeight = (std::abs(angle_) == 90) ? (fontSize_ + lineSpacing_) * infosSize_
                                              : lineSpacing_ * 2 + fontSize_;
    if (pluginFrameSize_.first == 0 || pluginFrameSize_.second == 0)
        return;

    if (infosposition_ == "1") {
        points_[1] = {pluginFrameSize_.first - margin, margin};
    } else if (infosposition_ == "2") {
        points_[1] = {margin, margin};
    } else if (infosposition_ == "3") {
        points_[1] = {margin, pluginFrameSize_.second - margin};
    } else if (infosposition_ == "4") {
        points_[1] = {pluginFrameSize_.first - margin, pluginFrameSize_.second - margin};
    }
    if (logoposition_ == "1") {
        points_[0] = {pluginFrameSize_.first - mark_->width - margin / 2, margin};
    } else if (logoposition_ == "2") {
        points_[0] = {margin / 2, margin};
    } else if (logoposition_ == "3") {
        points_[0] = {margin / 2, pluginFrameSize_.second - markHeight - margin};
    } else if (logoposition_ == "4") {
        points_[0] = {pluginFrameSize_.first - markWidth - margin / 2,
                      pluginFrameSize_.second - markHeight - margin};
    }

    if (infosposition_ == logoposition_ && showInfos_ && showLogo_) {
        if (logoposition_ == "1" || logoposition_ == "2") {
            points_[0].second += infoHeight;
        } else if (logoposition_ == "3" || logoposition_ == "4") {
            points_[0].second -= infoHeight;
        }
    }
}

void
WatermarkVideoSubscriber::update(jami::Observable<AVFrame*>*, AVFrame* const& pluginFrame)
{
    if (!observable_ || !pluginFrame || (!validLogo_ && showLogo_))
        return;

    AVFrameSideData* side_data = av_frame_get_side_data(pluginFrame, AV_FRAME_DATA_DISPLAYMATRIX);
    int newAngle {0};
    if (side_data) {
        auto matrix_rotation = reinterpret_cast<int32_t*>(side_data->data);
        newAngle = static_cast<int>(av_display_rotation_get(matrix_rotation));
    }
    if (newAngle != angle_) {
        angle_ = newAngle;
        firstRun = true;
    }

    //======================================================================================
    // GET RAW FRAME
    uniqueFramePtr rgbFrame = {transferToMainMemory(pluginFrame, AV_PIX_FMT_NV12), frameFree};
    rgbFrame.reset(FrameScaler::convertFormat(rgbFrame.get(), AV_PIX_FMT_YUV420P));
    if (!rgbFrame.get())
        return;
    rgbFrame->pts = 1;

    if (firstRun) {
        pluginFilter_.clean();
        infosFilter_.clean();
        pluginFrameSize_ = {rgbFrame->width, rgbFrame->height};
        if (std::abs(angle_) == 90)
            pluginFrameSize_ = {rgbFrame->height, rgbFrame->width};

        setFilterDescription();

        rational<int> fr(rgbFrame->pts, 1);
        pluginstream_ = MediaStream("input",
                                    rgbFrame->format,
                                    1 / fr,
                                    rgbFrame->width,
                                    rgbFrame->height,
                                    0,
                                    fr);

        if (showLogo_) {
            MediaStream markstream_ = MediaStream("mark",
                                                  mark_->format,
                                                  logoStream_.timeBase,
                                                  mark_->width,
                                                  mark_->height,
                                                  0,
                                                  logoStream_.frameRate);
            pluginFilter_.initialize(pluginFilterDescription_, {markstream_, pluginstream_});
            pluginFilter_.feedInput(mark_.get(), "mark");
            pluginFilter_.feedEOF("mark");
        }

        infosFilter_.initialize(infosDescription_, {pluginstream_});
        firstRun = false;
    }

    if (!infosFilter_.initialized_ && !pluginFilter_.initialized_)
        return;

    if (showLogo_) {
        if (pluginFilter_.feedInput(rgbFrame.get(), "input") == 0) {
            uniqueFramePtr filteredFrame = {pluginFilter_.readOutput(), frameFree};
            if (filteredFrame.get())
                moveFrom(rgbFrame.get(), filteredFrame.get());
        }
    }
    if (showInfos_) {
        if (infosFilter_.feedInput(rgbFrame.get(), "input") == 0) {
            uniqueFramePtr filteredFrame = {infosFilter_.readOutput(), frameFree};
            if (filteredFrame.get())
                moveFrom(rgbFrame.get(), filteredFrame.get());
        }
    }
    if (showInfos_ || showLogo_) {
        moveFrom(pluginFrame, rgbFrame.get());
    }
}

void
WatermarkVideoSubscriber::attached(jami::Observable<AVFrame*>* observable)
{
    Plog::log(Plog::LogPriority::INFO, TAG, "Attached!");
    observable_ = observable;
}

void
WatermarkVideoSubscriber::detached(jami::Observable<AVFrame*>*)
{
    pluginFilter_.clean();
    infosFilter_.clean();
    firstRun = true;
    observable_ = nullptr;
    Plog::log(Plog::LogPriority::INFO, TAG, "Detached!");
    mtx_.unlock();
}

void
WatermarkVideoSubscriber::detach()
{
    if (observable_) {
        mtx_.lock();
        firstRun = true;
        observable_->detach(this);
    }
}
} // namespace jami
