//
//
//

#define DBG_LEVEL 3
#include "Raym/Log.h"

#include "HTTPLiveStreaming.h"

using namespace Raym;

namespace ry0
{
namespace iPTd
{

HTTPLiveStreaming::HTTPLiveStreaming()
{
    DebugLog2("HTTPLiveStreaming::HTTPLiveStreaming()");

    _source      = NULL;
    _output_path = NULL;
    _index_name  = NULL;
    _base_url    = NULL;
    _counter     = 0;
}

HTTPLiveStreaming::~HTTPLiveStreaming()
{
    RELEASE(_source);
    RELEASE(_output_path);
    RELEASE(_index_name);
    RELEASE(_base_url);

    DebugLog2("HTTPLiveStreaming::~HTTPLiveStreaming()");
}

HTTPLiveStreaming *HTTPLiveStreaming::alloc()
{
    DebugLog2("HTTPLiveStreaming::alloc()");

    return new HTTPLiveStreaming();
}

HTTPLiveStreaming *HTTPLiveStreaming::init()
{
    DebugLog2("HTTPLiveStreaming::init()");

    if (FFmpeg::init() == NULL)
    {
        release();
        return NULL;
    }

    return this;
}

HTTPLiveStreaming *HTTPLiveStreaming::retain()
{
    DebugLog2("HTTPLiveStreaming::retain()");

    FFmpeg::retain();
    return this;
}

HTTPLiveStreaming *HTTPLiveStreaming::autorelease()
{
    DebugLog2("HTTPLiveStreaming::autorelease()");

    FFmpeg::autorelease();
    return this;
}

void HTTPLiveStreaming::setSource(String *source)
{
    DebugLog2("HTTPLiveStreaming::setSource()");

    RELEASE(_source);
    if (source != NULL)
    {
        _source = source->retain();
    }
}

void HTTPLiveStreaming::setOutputPath(String *output_path)
{
    DebugLog2("HTTPLiveStreaming::setOutputPath()");

    RELEASE(_output_path);
    if (output_path != NULL)
    {
        _output_path = output_path->retain();
    }
}

String *HTTPLiveStreaming::outputPath()
{
    return _output_path;
}

void HTTPLiveStreaming::setIndexName(String *index_name)
{
    DebugLog2("HTTPLiveStreaming::setIndexName()");

    RELEASE(_index_name);
    if (index_name != NULL)
    {
        _index_name = index_name->retain();
    }
}

bool HTTPLiveStreaming::start()
{
    DebugLog2("%s", __FUNCTION__);

    if ((_output_path == NULL) || (_source == NULL) || (_index_name == NULL))
    {
        return false;
    }

    DebugLog2("output path: %s", _output_path->cString());
    DebugLog2("source: %s", _source->cString());
    DebugLog2("index: %s", _index_name->cString());

    String *index_path = indexPath();
    if (index_path != NULL)
    {
        FileManager::defaultManager()->removeItemAtPath(index_path, NULL);
    }

    //
    // %>ffmpeg -i C:\WORK\20151024_211758_086_PT2@050000-01.ts -vcodec libx264 -r 30000/1001 -aspect 16:9 -s 1280x720
    // -bufsize 20000k -maxrate 25000k -acodec libvo_aacenc -ac
    // 2 -ar 48000 -ab 128k -threads 2 -f segment -segment_format mpegts -segment_time 10 -segment_list index.m3u8 test%03d.ts
    //

    // 暫定処理
//    Array *args = STR_ARRAY("-i",              "C:\\WORK\\20151024_211758_086_PT2@050000-01.ts",
//    Array *args = STR_ARRAY("-i",              "udp://0.0.0.0:51027",
#if 0
    Array *arg2 = STR_ARRAY("-i",              "udp://@0.0.0.0:51027?overrun_nonfatal=1&fifo_size=50000000",
//    Array *args = STR_ARRAY("-i",              "udp://@51027?overrun_nonfatal=1&fifo_size=50000000",
                              "-vcodec",         "libx264",
                              "-r",              "30000/1001",
                              "-aspect",         "16:9",
                              "-s",              "1280x720",
                              "-bufsize",        "20000k",
                              "-maxrate",        "25000k",
                              "-acodec",         "libvo_aacenc",
                              "-ac",             "2",
                              "-ar",             "48000",
                              "-ab",             "128k",
                              "-threads",        "2",
//                              "-programid",      "1074",
                              "-f",              "segment",
                              "-segment_format", "mpegts",
                              "-segment_time",   "10",
                              "-segment_list",   "C:\\WORK\\www\\index.m3u8",
                              "C:\\WORK\\www\\test%03d.ts",
                              NULL);
#endif

    Array *args = Array::arrayWithCapacity(0);
    args->addObject(String::stringWithUTF8String("-i"));
//    args->addObject(String::stringWithUTF8String("udp://@0.0.0.0:51027?overrun_nonfatal=1&fifo_size=50000000"));
    if (_source->hasPrefix("udp://"))
    {
        args->addObject(String::stringWithFormat("%s?overrun_nonfatal=1&fifo_size=50000000", _source->cString()));
    }
    else
    {
        args->addObject(String::stringWithUTF8String("hogehoge"));
    }

    args->addObject(String::stringWithUTF8String("-vcodec"));
    args->addObject(String::stringWithUTF8String("libx264"));
    args->addObject(String::stringWithUTF8String("-r"));
    args->addObject(String::stringWithUTF8String("30000/1001"));
    args->addObject(String::stringWithUTF8String("-aspect"));
    args->addObject(String::stringWithUTF8String("16:9"));
//    args->addObject(String::stringWithUTF8String("-s"));
//    args->addObject(String::stringWithUTF8String("1280x720"));
    args->addObject(String::stringWithUTF8String("-g"));
    args->addObject(String::stringWithUTF8String("150"));
    args->addObject(String::stringWithUTF8String("-bufsize"));
    args->addObject(String::stringWithUTF8String("20000k"));
    args->addObject(String::stringWithUTF8String("-maxrate"));
    args->addObject(String::stringWithUTF8String("25000k"));
    args->addObject(String::stringWithUTF8String("-acodec"));
    args->addObject(String::stringWithUTF8String("libvo_aacenc"));
    args->addObject(String::stringWithUTF8String("-ac"));
    args->addObject(String::stringWithUTF8String("2"));
    args->addObject(String::stringWithUTF8String("-ar"));
    args->addObject(String::stringWithUTF8String("48000"));
    args->addObject(String::stringWithUTF8String("-ab"));
    args->addObject(String::stringWithUTF8String("128k"));
    args->addObject(String::stringWithUTF8String("-threads"));
    args->addObject(String::stringWithUTF8String("2"));
    args->addObject(String::stringWithUTF8String("-f"));
    args->addObject(String::stringWithUTF8String("segment"));
    args->addObject(String::stringWithUTF8String("-segment_format"));
    args->addObject(String::stringWithUTF8String("mpegts"));
    args->addObject(String::stringWithUTF8String("-segment_time"));
    args->addObject(String::stringWithUTF8String("10"));

    args->addObject(String::stringWithUTF8String("-segment_list"));
    args->addObject(_output_path->stringByAppendingPathComponent(String::stringWithFormat("%s.m3u8", _index_name->cString())));

    args->addObject(_output_path->stringByAppendingPathComponent(String::stringWithUTF8String("streaming-%05d.ts")));

    setArguments(args);

    return FFmpeg::start();
}

String * HTTPLiveStreaming::indexPath()
{
    if ((_output_path == NULL) || (_index_name == NULL))
    {
        return false;
    }
    return _output_path->stringByAppendingPathComponent(String::stringWithFormat("%s.m3u8", _index_name->cString()));
}


bool HTTPLiveStreaming::readLine(String *line)
{
    if (line != NULL)
    {
//        DebugLog3("ffmpeg: %s", line->cString());
    }
    return false;
}

const char *HTTPLiveStreaming::className()
{
    return "HTTPLiveStreaming";
}

} // iPTd
} // ry0
