#!/usr/bin/python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
# Copyright (C) 2009-2011 Canonical Ltd
#
# 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 2 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


import gettext
import logging
import optparse
import os
import sys, subprocess
from re import search, sub
from shutil import copy, copytree

import gettext
from gettext import gettext as _
gettext.textdomain('magomatic')

# Add project root directory (enable symlink, and trunk execution).
PROJECT_ROOT_DIRECTORY = os.path.abspath(
    os.path.dirname(os.path.dirname(os.path.realpath(sys.argv[0]))))

if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY, 'mago'))
    and PROJECT_ROOT_DIRECTORY not in sys.path):
    sys.path.insert(0, PROJECT_ROOT_DIRECTORY)
    os.putenv('PYTHONPATH', PROJECT_ROOT_DIRECTORY) # for subprocesses

from mago import magomaticconfig
from mago import magomatic

LEVELS = (  logging.ERROR,
            logging.WARNING,
            logging.INFO,
            logging.DEBUG,
            )

def xprop():
    (command, appname) = (None, None)
    (wmname, wmtype) = (None, None)
    print "\
Please select the window about which you would like information \n\
by clicking the mouse in that window."

    try:
        sp = subprocess.Popen(['xprop','_NET_WM_PID', 'WM_NAME',
                               '_NET_WM_WINDOW_TYPE'], stdin=None,
                              stdout=subprocess.PIPE, stderr=None)
    except OSError, e:
        return [127, str(e)]
    out = sp.communicate()[0]
    for line in out.split('\n'):
        m = search('([^\(]+).* = (.+)', line)
        if m:
            wmprop = m.group(1)
            wmvalue = m.group(2)

            if wmprop.startswith('_NET_WM_PID'):
                try:
                    f = open('/proc/%d/comm' % int(wmvalue), 'rb')
                    command = f.read().strip()
                    f.close()
                except IOError, e:
                    # Parent process may not exists anymore when it forks
                    if e.errno == 2: # File does not exist
                        return (None, None)
                    else:
                        raise IOError,e
            elif wmprop.startswith('WM_NAME'):
                # Remove quotes and spaces to match naming conventions of ldtp
                wmname = wmvalue[1:-1].replace(' ','') 
            elif wmprop.startswith('_NET_WM_WINDOW_TYPE'):
                if 'NORMAL' in wmvalue:
                    wmtype = 'frm'
                elif 'DIALOG' in wmvalue:
                    wmtype = 'dlg'

    if wmname and wmtype:
        appname = wmtype + wmname

    return (command, appname)

def publish_to_mago(suitename, magodir):
    """ Copy a testsuite generated by magomatic to a mago tree"""
    logging.debug("Publishing '%s' to '%s' " % (suitename, magodir))

    # Check if the testsuite is there
    suitedir = magomaticconfig.get_data_file(suitename)
    appname = sub('\W', '_', suitename)

    for d in ('application', 'test_suite', appname):
        dp = os.path.join(suitedir,d)
        logging.debug("Checking if '%s' exists" % dp)
        if not os.path.exists(dp):
            print "E: Path '%s' does not exists. Exiting" % dp
            sys.exit(1)
    # Check if the destination directory exits
    for d in ('', 'mago/application','mago/test_suite'):
        mp = os.path.join(magodir,d)
        logging.debug("Checking if '%s' exists" % mp)
        if not os.path.exists(mp):
            print "E: Destination directory '%s' does not exists. Exiting" % mp
            sys.exit(2)

    # Everything is there, do the copy
    destdir = os.path.join(magodir, appname)
    logging.debug("Copying '%s' to '%s'" % (os.path.join(suitedir, appname), destdir))
    copytree(os.path.join(suitedir, appname), destdir)

    destdir = os.path.join(magodir, 'mago/application')
    logging.debug("Copying '%s' to '%s'" % (os.path.join(suitedir, "application", appname + ".py"), destdir))
    copy(os.path.join(suitedir, "application", appname + ".py"), destdir)
    destdir = os.path.join(magodir, 'mago/test_suite')
    logging.debug("Copying '%s' to '%s'" % (os.path.join(suitedir, "test_suite", appname + ".py"), destdir))
    copy(os.path.join(suitedir, "test_suite", appname + ".py"), destdir)

if __name__ == "__main__":

    version = magomaticconfig.__magomatic_data_directory__
    # Support for command line options.
    usage = _("magomatic [options] app_launcher main_window_title")
    parser = optparse.OptionParser(version="magomatic %s" % version, usage=usage)
    parser.add_option('-c', '--child', dest='child_window', action='store_true',
        default=False, help=_('Child window to navigate'))
    parser.add_option('-d', '--debug', dest='debug_mode', action='store_true',
        help=_('Print the maximum debugging info (implies -vv)'))
    parser.add_option('-o', '--overwrite', dest='overwrite', action='store_true',
        default=False,help=_('Overwrite existing files'))
    parser.add_option('-t', '--tree', dest='dumptree', action='store_true',
        default=False,help=_('Dump component tree'))
    parser.add_option('-v', '--verbose', dest='logging_level', action='count',
        help=_('set error_level output to warning, info, and then debug'))
    #parser.add_option('-p', '--publishto', dest='publish_to', metavar="DEST",
    #    help=_('Publish the application passed in argument to DEST (mago root directory)'))
    parser.set_defaults(logging_level=0, foo=None)
    (options, args) = parser.parse_args()

    # set the verbosity
    if options.debug_mode:
        options.logging_level = 3
    logging.basicConfig(level=LEVELS[options.logging_level], format='%(asctime)s %(levelname)s %(message)s')
    child_window = options.child_window
    overwrite = options.overwrite

    #if options.publish_to:
    #    if len(args) != 1:
    #        print "E: Name of the testsuite to publish is missing"
    #        sys.exit(0)
    #
    #    publish_to_mago(args[0], options.publish_to)
    #    sys.exit(0)

    if len(args) == 0:
        # Run xprop to guess the window name and binary
        (app_launcher, main_window) = xprop()
        if not app_launcher or not main_window:
            print "E: Unable to find information about that window."
            sys.exit(1)
    elif len(args) == 1:
        app_launcher = args[0]
        main_window = None
    else:
        app_launcher = args[0]
        main_window = args[1]

    magomatic = magomatic.Magomatic(app_launcher, main_window,
                                    child_window, overwrite)
    magomatic.create_app_folder()
    magomatic.discover_application(options.dumptree)

    logging.debug(_('end of prog'))
