#!/usr/bin/env python
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#

import os
import sys
import tempfile

from subprocess import call
from shutil     import rmtree

import logging
import unittest


def banner():
    """
    Display interpreter and system info for the test env
    """
    print '*' * 75
    cmd = os.path.basename(__file__)
    print "%s: python version is %s" % (cmd, sys.version)
    print '*' * 75


def myopts(vals):
    """
    Storage for extra command line args passed.

    Returns:
    hash - argparse::Namespace object values
    """

    if not hasattr(myopts, 'vals'):
        if 'argparse' in sys.modules:
            tmp = { } # key existance enables unittest module debug
        else:
            tmp = { 'debug': False, 'verbose': False }

        for k in dir(vals):
            if k[0:1] == '_':
                continue
            tmp[k] = getattr(vals, k)
        myopts.vals = tmp

    return myopts.vals
    

def path2posix(src):
    """
    Normalize directory path syntax

    Keyword arguments:
    src - path to normalize

    Returns:
    scalar - a file path with drive separators and windows slashes removed

    Todo:
    move to {build,config,tools,toolkit}/python for use in a library
    """

    ## (drive, tail) = os.path.splitdrive(src)
    ## Support path testing on all platforms
    drive = ''
    winpath = src.find(':')
    if -1 != winpath and 10 > winpath:
        (drive, tail) = src.split(':', 1)

    if drive:
        todo = [ '', drive.rstrip(':').lstrip('/').lstrip('\\') ]
        todo.extend( tail.lstrip('/').lstrip('\\').split('\\') ) # c:\a => [a]
    else: # os.name == 'posix'
        todo = src.split('\\')

    dst = '/'.join(todo)
    return dst
    

def checkMkdir(work, debug=False):
    """
    Verify arg permutations for directory mutex creation.

    Keyword arguments:
    None

    Returns:
    Exception on error

    Note:
    Exception() rather than self.assertTrue() is used in this test
    function to enable scatch cleanup on test exit/failure conditions.
    Not guaranteed by python closures on early exit.
    """

    logging.debug("Testing: checkMkdir")

    # On Windows, don't convert paths to POSIX
    skipposix = sys.platform == "win32"
    if skipposix:
        path = os.path.abspath(__file__)
        dirname_fun = os.path.dirname
    else:
        path = path2posix(os.path.abspath(__file__))
        import posixpath
        dirname_fun = posixpath.dirname

    src = dirname_fun(path)
    # root is 5 directories up from path
    root = reduce(lambda x, _: dirname_fun(x), xrange(5), path)

    rootP = path2posix(root)
    srcP  = path2posix(src)
    workP = path2posix(work)

    # C:\foo -vs- /c/foo
    # [0] command paths use /c/foo
    # [1] os.path.exists() on mingw() requires C:\
    paths = [
        "mkdir_bycall", # function generated
        "mkdir_bydep",  # explicit dependency
        "mkdir_bygen",  # by GENERATED_DIRS macro
    ]

    ## Use make from the parent "make check" call when available
    cmd = { 'make': 'make' }
    shell0 = os.environ.get('MAKE')
    if shell0:
        shell = os.path.splitext(shell0)[0] # strip: .exe, .py
        if -1 != shell.find('make'):
            print "MAKE COMMAND FOUND: %s" % (shell0)
            cmd['make'] = shell0 if skipposix else path2posix(shell0)

    args = []
    args.append('%s' % (cmd['make']))
    args.append('-C %s'                % (work if skipposix else workP))
    args.append("-f %s/testor.tmpl"    % (src if skipposix else srcP))
    args.append('topsrcdir=%s'         % (root if skipposix else rootP))
    args.append('deps_mkdir_bycall=%s' % paths[0])
    args.append('deps_mkdir_bydep=%s'  % paths[1])
    args.append('deps_mkdir_bygen=%s'  % paths[2])
    args.append('checkup') # target

    # Call will fail on mingw with output redirected ?!?
    if debug:
        pass
    if False: # if not debug:
        args.append('>/dev/null')

    cmd = '%s' % (' '.join(args))
    logging.debug("Running: %s" % (cmd))
    rc = call(cmd, shell=True)
    if rc:
        raise Exception("make failed ($?=%s): cmd=%s" % (rc, cmd))

    for i in paths:
        path = os.path.join(work, i)
        logging.debug("Did testing mkdir(%s) succeed?" % (path))
        if not os.path.exists(path):
            raise Exception("Test path %s does not exist" % (path))


def parseargs():
    """
    Support additional command line arguments for testing
    
    Returns:
    hash - arguments of interested parsed from the command line
    """

    opts = None
    try:
        import argparse2
        parser = argparse.ArgumentParser()
        parser.add_argument('--debug',
                            action="store_true",
                            default=False,
                            help='Enable debug mode')
        # Cannot overload verbose, Verbose: False enables debugging
        parser.add_argument('--verbose',
                            action="store_true",
                            default=False,
                            help='Enable verbose mode')
        parser.add_argument('unittest_args',
                            nargs='*'
                            # help='Slurp/pass remaining args to unittest'
                            )
        opts = parser.parse_args()

    except ImportError:
        pass

    return opts


class TestMakeLogic(unittest.TestCase):
    """
    Test suite used to validate makefile library rules and macros
    """

    def setUp(self):
        opts = myopts(None) # NameSpace object not hash
        self.debug   = opts['debug']
        self.verbose = opts['verbose']

        if self.debug:
            logging.basicConfig(level=logging.DEBUG)

        if self.verbose:
            print
            print "ENVIRONMENT DUMP:"
            print '=' * 75
            for k,v in os.environ.items():
                print "env{%s} => %s" % (k, v)
            print


    def test_path2posix(self):

        todo = {
            '/dev/null'     : '/dev/null',
            'A:\\a\\b\\c'   : '/A/a/b/c',
            'B:/x/y'        : '/B/x/y',
            'C:/x\\y/z'     : '/C/x/y/z',
            '//FOO/bar/tans': '//FOO/bar/tans',
            '//X\\a/b\\c/d' : '//X/a/b/c/d',
            '\\c:mozilla\\sandbox': '/c/mozilla/sandbox',
        }

        for val,exp in todo.items():
            found = path2posix(val)
            tst = "posix2path(%s): %s != %s)" % (val, exp, found)
            self.assertEqual(exp, found, "%s: invalid path detected" % (tst))


    def test_mkdir(self):
        """
        Verify directory creation rules and macros
        """

        failed = True

        # Exception handling is used to cleanup scratch space on error
        try:
            work = tempfile.mkdtemp()
            checkMkdir(work, self.debug)
            failed = False
        finally:
            if os.path.exists(work):
                rmtree(work)

        self.assertFalse(failed, "Unit test failure detected")


if __name__ == '__main__':
    banner()
    opts = parseargs()
    myopts(opts)

    if opts:
        if hasattr(opts, 'unittest_args'):
            sys.argv[1:] = opts.unittest_args
        else:
            sys.argv[1:] = []

    unittest.main()
