#!/usr/bin/python3
# -*- coding: utf-8 -*-

# Copyright (C) 2015 Canonical Ltd.
# Author: Christopher Townsend <christopher.townsend@canonical.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; version 3 of the License.
#
# 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, see <http://www.gnu.org/licenses/>.

import argparse
import os
import libertine.utils
import psutil
import shlex
import time
from libertine import LibertineContainer


def set_dbus_session_socket_path():
    unique_id = os.environ['DISPLAY'].strip(':')

    if not os.path.exists(libertine.utils.get_libertine_runtime_dir()):
        os.makedirs(libertine.utils.get_libertine_runtime_dir())

    dbus_session_socket_path = (
        os.path.join(libertine.utils.get_libertine_runtime_dir(), 'host_dbus_session' + unique_id))

    os.environ['DBUS_SESSION_BUS_ADDRESS'] = "unix:path=" + dbus_session_socket_path

    return dbus_session_socket_path


def launch_libertine_session_bridge(session_socket_path):
    libertine_session_bridge_cmd = "libertine-session-bridge " + session_socket_path

    args = shlex.split(libertine_session_bridge_cmd)
    return psutil.Popen(args)


def detect_session_bridge_socket(session_socket_path):
    retries = 0

    while not os.path.exists(session_socket_path):
        if retries >= 10:
            raise RuntimeError("Timeout waiting for Libertine Dbus session bridge socket") 
        
        print("Libertine Dbus session bridge socket is not ready.  Waiting...")
        retries += 1
        time.sleep(.5)


if __name__ == '__main__':
    arg_parser = argparse.ArgumentParser(description='launch an application in a Libertine container')
    arg_parser.add_argument('container_id',
                            help='Libertine container ID')
    arg_parser.add_argument('app_exec_line', nargs=argparse.REMAINDER,
                            help='exec line')
    args = arg_parser.parse_args()

    if not libertine.utils.container_exists(args.container_id):
        raise RuntimeError("Container ID %s does not exist." % args.container_id)

    session_socket_path = set_dbus_session_socket_path()

    session_bridge = launch_libertine_session_bridge(session_socket_path)

    detect_session_bridge_socket(session_socket_path)

    container = LibertineContainer(args.container_id) 

    try:
        container.launch_application(args.app_exec_line)
    except:
        raise
    finally:
        session_bridge.terminate()
