#!/usr/bin/env python

import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstBase', '1.0')

from gi.repository import GObject, Gst, GstBase

import os
import gdp
import sys
import cPickle

import gdpsrc, gdpsink

if __name__ == '__main__':

    sys.stderr.write("THIS IS ONLY A PROOF-OF-CONCEPT, USE AT YOUR OWN RISK!\n")

    GObject.threads_init()
    Gst.init(None)

    # register the elements again, just in case
    Gst.Element.register(None, "gdpsrc", Gst.Rank.NONE, gdpsrc.GDPSrc)
    Gst.Element.register(None, "gdpsink", Gst.Rank.NONE, gdpsink.GDPSink)

    if len(sys.argv)<2:
        sys.stderr.write("Usage: %s <a valid pipeline>\n" % sys.argv[0])
        sys.stderr.write("Example: audiotestsrc ! gdpsink logname=xyz\n")
        sys.stderr.write("Example: gdpsrc logname=xyz ! autoaudiosink\n")
        sys.stderr.write("Valid properties are 'logname' and 'name'.\n")
        sys.exit(-1)

    pipeline_desc = " ".join(sys.argv[1:])

    # Not sure if escaping is allowed. If so, this doesn't work well.
    orig_elems = pipeline_desc.split("!")
    assert len(orig_elems)>=2

    # Because of a weird bug somewhere (most likely in Python Gstreamer),
    # setting properties for python plugins (other than 'name') does not
    # work from the pipeline description passed to Gst.parse_launch. It
    # does, however, work if we get a handle to the element and call
    # 'set_property' on it explicitly.
    # To get around this bug, we must parse the pipeline description, find
    # our particular elements, generate a pipeline without the property
    # assignments, create the pipeline by calling Gst.parse_launch, then
    # get all our elements, and individually set properties on them.

    # Original properties specified in the pipeline description
    # A list of dicts, each item in the list represents our elements
    gdp_elem_list = []

    # A list of strings representing elements in the modified pipeline desc
    new_elems = []

    for elem in orig_elems:
        # elem is simply a string representing an element and its property
        # assignment
        elem = elem.strip()
        _elem = elem.split(" ")[0]

        if _elem == "gdpsrc" or _elem == "gdpsink":
            # parse the properties.
            props = {}
            __prop_strs = elem.split(" ")[1:]
            for __prop_str in __prop_strs:
                __prop_str = __prop_str.strip()
                _tmp = __prop_str.split("=")
                props[_tmp[0]] = _tmp[1]

            # ensure that we have the 'name' set
            props["name"] = props.get("name",
                                "%s%d" % (_elem, len(gdp_elem_list)))

            # parsed properties, now recreate this element
            elem = "%s name=%s" % (_elem, props["name"])
            gdp_elem_list.append(props)

        new_elems.append(elem)

    new_pipeline_desc = " ! ".join(new_elems)

    sys.stderr.write("Modified original pipeline\n")
    sys.stderr.write("launching pipeline %s\n" % new_pipeline_desc)
    pipeline = Gst.parse_launch(new_pipeline_desc)

    # Now is the time to set properties to each of the GDP elements
    for props in gdp_elem_list:
        elem_name = props["name"]
        elem = pipeline.get_by_name(elem_name)

        for key in props:
            if key == "name":
                continue
            elem.set_property(key, props[key])

    # All set, ready to go now
    pipeline.set_state(Gst.State.PLAYING)

    loop = GObject.MainLoop()
    try:
        loop.run()
    except:
        pass

    pipeline.set_state(Gst.State.NULL)
