import subprocess
import unittest
import sys
import os
import imp
from tempfile import mkdtemp
from shutil import rmtree
import mozunit

from UserString import UserString
# Create a controlled configuration for use by expandlibs
config_win = {
    'AR': 'lib',
    'AR_EXTRACT': '',
    'DLL_PREFIX': '',
    'LIB_PREFIX': '',
    'OBJ_SUFFIX': '.obj',
    'LIB_SUFFIX': '.lib',
    'DLL_SUFFIX': '.dll',
    'IMPORT_LIB_SUFFIX': '.lib',
    'LIBS_DESC_SUFFIX': '.desc',
    'EXPAND_LIBS_LIST_STYLE': 'list',
}
config_unix = {
    'AR': 'ar',
    'AR_EXTRACT': 'ar -x',
    'DLL_PREFIX': 'lib',
    'LIB_PREFIX': 'lib',
    'OBJ_SUFFIX': '.o',
    'LIB_SUFFIX': '.a',
    'DLL_SUFFIX': '.so',
    'IMPORT_LIB_SUFFIX': '',
    'LIBS_DESC_SUFFIX': '.desc',
    'EXPAND_LIBS_LIST_STYLE': 'linkerscript',
}

config = sys.modules['expandlibs_config'] = imp.new_module('expandlibs_config')

from expandlibs import LibDescriptor, ExpandArgs, relativize
from expandlibs_gen import generate
from expandlibs_exec import ExpandArgsMore, SectionFinder

def Lib(name):
    return config.LIB_PREFIX + name + config.LIB_SUFFIX

def Obj(name):
    return name + config.OBJ_SUFFIX

def Dll(name):
    return config.DLL_PREFIX + name + config.DLL_SUFFIX

def ImportLib(name):
    if not len(config.IMPORT_LIB_SUFFIX): return Dll(name)
    return config.LIB_PREFIX + name + config.IMPORT_LIB_SUFFIX

class TestRelativize(unittest.TestCase):
    def test_relativize(self):
        '''Test relativize()'''
        os_path_exists = os.path.exists
        def exists(path):
            return True
        os.path.exists = exists
        self.assertEqual(relativize(os.path.abspath(os.curdir)), os.curdir)
        self.assertEqual(relativize(os.path.abspath(os.pardir)), os.pardir)
        self.assertEqual(relativize(os.path.join(os.curdir, 'a')), 'a')
        self.assertEqual(relativize(os.path.join(os.path.abspath(os.curdir), 'a')), 'a')
        # relativize is expected to return the absolute path if it is shorter
        self.assertEqual(relativize(os.sep), os.sep)
        os.path.exists = os.path.exists

class TestLibDescriptor(unittest.TestCase):
    def test_serialize(self):
        '''Test LibDescriptor's serialization'''
        desc = LibDescriptor()
        desc[LibDescriptor.KEYS[0]] = ['a', 'b']
        self.assertEqual(str(desc), "{0} = a b".format(LibDescriptor.KEYS[0]))
        desc['unsupported-key'] = ['a']
        self.assertEqual(str(desc), "{0} = a b".format(LibDescriptor.KEYS[0]))
        desc[LibDescriptor.KEYS[1]] = ['c', 'd', 'e']
        self.assertEqual(str(desc),
                         "{0} = a b\n{1} = c d e"
                         .format(LibDescriptor.KEYS[0], LibDescriptor.KEYS[1]))
        desc[LibDescriptor.KEYS[0]] = []
        self.assertEqual(str(desc), "{0} = c d e".format(LibDescriptor.KEYS[1]))

    def test_read(self):
        '''Test LibDescriptor's initialization'''
        desc_list = ["# Comment",
                     "{0} = a b".format(LibDescriptor.KEYS[1]),
                     "", # Empty line
                     "foo = bar", # Should be discarded
                     "{0} = c d e".format(LibDescriptor.KEYS[0])]
        desc = LibDescriptor(desc_list)
        self.assertEqual(desc[LibDescriptor.KEYS[1]], ['a', 'b'])
        self.assertEqual(desc[LibDescriptor.KEYS[0]], ['c', 'd', 'e'])
        self.assertEqual(False, 'foo' in desc)

def wrap_method(conf, wrapped_method):
    '''Wrapper used to call a test with a specific configuration'''
    def _method(self):
        for key in conf:
            setattr(config, key, conf[key])
        self.init()
        try:
            wrapped_method(self)
        except:
            raise
        finally:
            self.cleanup()
    return _method

class ReplicateTests(type):
    '''Replicates tests for unix and windows variants'''
    def __new__(cls, clsName, bases, dict):
        for name in [key for key in dict if key.startswith('test_')]:
            dict[name + '_unix'] = wrap_method(config_unix, dict[name])
            dict[name + '_unix'].__doc__ = dict[name].__doc__ + ' (unix)'
            dict[name + '_win'] = wrap_method(config_win, dict[name])
            dict[name + '_win'].__doc__ = dict[name].__doc__ + ' (win)'
            del dict[name]
        return type.__new__(cls, clsName, bases, dict)

class TestCaseWithTmpDir(unittest.TestCase):
    __metaclass__ = ReplicateTests
    def init(self):
        self.tmpdir = os.path.abspath(mkdtemp(dir=os.curdir))

    def cleanup(self):
        rmtree(self.tmpdir)

    def touch(self, files):
        for f in files:
            open(f, 'w').close()

    def tmpfile(self, *args):
        return os.path.join(self.tmpdir, *args)

class TestExpandLibsGen(TestCaseWithTmpDir):
    def test_generate(self):
        '''Test library descriptor generation'''
        files = [self.tmpfile(f) for f in
                 [Lib('a'), Obj('b'), Lib('c'), Obj('d'), Obj('e'), Lib('f')]]
        self.touch(files[:-1])
        self.touch([files[-1] + config.LIBS_DESC_SUFFIX])

        desc = generate(files)
        self.assertEqual(desc['OBJS'], [self.tmpfile(Obj(s)) for s in ['b', 'd', 'e']])
        self.assertEqual(desc['LIBS'], [self.tmpfile(Lib(s)) for s in ['a', 'c', 'f']])

        self.assertRaises(Exception, generate, files + [self.tmpfile(Obj('z'))])
        self.assertRaises(Exception, generate, files + [self.tmpfile(Lib('y'))])

class TestExpandInit(TestCaseWithTmpDir):
    def init(self):
        ''' Initializes test environment for library expansion tests'''
        super(TestExpandInit, self).init()
        # Create 2 fake libraries, each containing 3 objects, and the second
        # including the first one and another library.
        os.mkdir(self.tmpfile('libx'))
        os.mkdir(self.tmpfile('liby'))
        self.libx_files = [self.tmpfile('libx', Obj(f)) for f in ['g', 'h', 'i']]
        self.liby_files = [self.tmpfile('liby', Obj(f)) for f in ['j', 'k', 'l']] + [self.tmpfile('liby', Lib('z'))]
        self.touch(self.libx_files + self.liby_files)
        with open(self.tmpfile('libx', Lib('x') + config.LIBS_DESC_SUFFIX), 'w') as f:
            f.write(str(generate(self.libx_files)))
        with open(self.tmpfile('liby', Lib('y') + config.LIBS_DESC_SUFFIX), 'w') as f:
            f.write(str(generate(self.liby_files + [self.tmpfile('libx', Lib('x'))])))

        # Create various objects and libraries 
        self.arg_files = [self.tmpfile(f) for f in [Lib('a'), Obj('b'), Obj('c'), Lib('d'), Obj('e')]]
        # We always give library names (LIB_PREFIX/SUFFIX), even for
        # dynamic/import libraries
        self.files = self.arg_files + [self.tmpfile(ImportLib('f'))]
        self.arg_files += [self.tmpfile(Lib('f'))]
        self.touch(self.files)

    def assertRelEqual(self, args1, args2):
        self.assertEqual(args1, [relativize(a) for a in args2])

class TestExpandArgs(TestExpandInit):
    def test_expand(self):
        '''Test library expansion'''
        # Expanding arguments means libraries with a descriptor are expanded
        # with the descriptor content, and import libraries are used when
        # a library doesn't exist
        args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
        self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 

        # When a library exists at the same time as a descriptor, we still use
        # the descriptor.
        self.touch([self.tmpfile('libx', Lib('x'))])
        args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
        self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files)

        self.touch([self.tmpfile('liby', Lib('y'))])
        args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
        self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files)

class TestExpandArgsMore(TestExpandInit):
    def test_makelist(self):
        '''Test grouping object files in lists'''
        # ExpandArgsMore does the same as ExpandArgs
        with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
            self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 

            # But also has an extra method replacing object files with a list
            args.makelist()
            # self.files has objects at #1, #2, #4
            self.assertRelEqual(args[:3], ['foo', '-bar'] + self.files[:1])
            self.assertRelEqual(args[4:], [self.files[3]] + self.files[5:] + [self.tmpfile('liby', Lib('z'))])

            # Check the list file content
            objs = [f for f in self.files + self.liby_files + self.libx_files if f.endswith(config.OBJ_SUFFIX)]
            if config.EXPAND_LIBS_LIST_STYLE == "linkerscript":
                self.assertNotEqual(args[3][0], '@')
                filename = args[3]
                content = ['INPUT("{0}")'.format(relativize(f)) for f in objs]
                with open(filename, 'r') as f:
                    self.assertEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
            elif config.EXPAND_LIBS_LIST_STYLE == "list":
                self.assertEqual(args[3][0], '@')
                filename = args[3][1:]
                content = objs
                with open(filename, 'r') as f:
                    self.assertRelEqual([l.strip() for l in f.readlines() if len(l.strip())], content)

            tmp = args.tmp
        # Check that all temporary files are properly removed
        self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))

    def test_extract(self):
        '''Test library extraction'''
        # Divert subprocess.call
        subprocess_call = subprocess.call
        subprocess_check_output = subprocess.check_output
        def call(args, **kargs):
            if config.AR == 'lib':
                self.assertEqual(args[:2], [config.AR, '-NOLOGO'])
                self.assertTrue(args[2].startswith('-EXTRACT:'))
                extract = [args[2][len('-EXTRACT:'):]]
                self.assertTrue(extract)
                args = args[3:]
            else:
                # The command called is always AR_EXTRACT
                ar_extract = config.AR_EXTRACT.split()
                self.assertEqual(args[:len(ar_extract)], ar_extract)
                args = args[len(ar_extract):]
            # Remaining argument is always one library
            self.assertEqual(len(args), 1)
            arg = args[0]
            self.assertEqual(os.path.splitext(arg)[1], config.LIB_SUFFIX)
            # Simulate file extraction
            lib = os.path.splitext(os.path.basename(arg))[0]
            if config.AR != 'lib':
                extract = [lib, lib + '2']
            extract = [os.path.join(kargs['cwd'], f) for f in extract]
            if config.AR != 'lib':
                extract = [Obj(f) for f in extract]
            if not lib in extracted:
                extracted[lib] = []
            extracted[lib].extend(extract)
            self.touch(extract)
        subprocess.call = call

        def check_output(args, **kargs):
            # The command called is always AR
            ar = config.AR
            self.assertEqual(args[0:3], [ar, '-NOLOGO', '-LIST'])
            # Remaining argument is always one library
            self.assertRelEqual([os.path.splitext(arg)[1] for arg in args[3:]],
[config.LIB_SUFFIX])
            # Simulate LIB -NOLOGO -LIST
            lib = os.path.splitext(os.path.basename(args[3]))[0]
            return '%s\n%s\n' % (Obj(lib), Obj(lib + '2'))
        subprocess.check_output = check_output

        # ExpandArgsMore does the same as ExpandArgs
        self.touch([self.tmpfile('liby', Lib('y'))])
        for iteration in (1, 2):
            with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
                files = self.files + self.liby_files + self.libx_files

                self.assertRelEqual(args, ['foo', '-bar'] + files)

                extracted = {}
                # ExpandArgsMore also has an extra method extracting static libraries
                # when possible
                args.extract()

                # With AR_EXTRACT, it uses the descriptors when there are, and
                # actually
                # extracts the remaining libraries
                extracted_args = []
                for f in files:
                    if f.endswith(config.LIB_SUFFIX):
                        base = os.path.splitext(os.path.basename(f))[0]
                        # On the first iteration, we test the behavior of
                        # extracting archives that don't have a copy of their
                        # contents next to them, which is to use the file
                        # extracted from the archive in a temporary directory.
                        # On the second iteration, we test extracting archives
                        # that do have a copy of their contents next to them,
                        # in which case those contents are used instead of the
                        # temporarily extracted files.
                        if iteration == 1:
                            extracted_args.extend(sorted(extracted[base]))
                        else:
                            dirname = os.path.dirname(f[len(self.tmpdir)+1:])
                            if base.endswith('f'):
                                dirname = os.path.join(dirname, 'foo', 'bar')
                            extracted_args.extend([self.tmpfile(dirname, Obj(base)), self.tmpfile(dirname, Obj(base + '2'))])
                    else:
                        extracted_args.append(f)
                self.assertRelEqual(args, ['foo', '-bar'] + extracted_args)

                tmp = args.tmp
            # Check that all temporary files are properly removed
            self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))

            # Create archives contents next to them for the second iteration.
            base = os.path.splitext(Lib('_'))[0]
            self.touch(self.tmpfile(Obj(base.replace('_', suffix))) for suffix in ('a', 'a2', 'd', 'd2'))
            try:
                os.makedirs(self.tmpfile('foo', 'bar'))
            except:
                pass
            self.touch(self.tmpfile('foo', 'bar', Obj(base.replace('_', suffix))) for suffix in ('f', 'f2'))
            self.touch(self.tmpfile('liby', Obj(base.replace('_', suffix))) for suffix in ('z', 'z2'))

        # Restore subprocess.call and subprocess.check_output
        subprocess.call = subprocess_call
        subprocess.check_output = subprocess_check_output

class FakeProcess(object):
    def __init__(self, out, err = ''):
        self.out = out
        self.err = err

    def communicate(self):
        return (self.out, self.err)

OBJDUMPS = {
'foo.o': '''
00000000 g     F .text\t00000001 foo
00000000 g     F .text._Z6foobarv\t00000001 _Z6foobarv
00000000 g     F .text.hello\t00000001 hello
00000000 g     F .text._ZThn4_6foobarv\t00000001 _ZThn4_6foobarv
''',
'bar.o': '''
00000000 g     F .text.hi\t00000001 hi
00000000 g     F .text.hot._Z6barbazv\t00000001 .hidden _Z6barbazv
''',
}

PRINT_ICF = '''
ld: ICF folding section '.text.hello' in file 'foo.o'into '.text.hi' in file 'bar.o'
ld: ICF folding section '.foo' in file 'foo.o'into '.foo' in file 'bar.o'
'''

class SubprocessPopen(object):
    def __init__(self, test):
        self.test = test

    def __call__(self, args, stdout = None, stderr = None):
        self.test.assertEqual(stdout, subprocess.PIPE)
        self.test.assertEqual(stderr, subprocess.PIPE)
        if args[0] == 'objdump':
            self.test.assertEqual(args[1], '-t')
            self.test.assertTrue(args[2] in OBJDUMPS)
            return FakeProcess(OBJDUMPS[args[2]])
        else:
            return FakeProcess('', PRINT_ICF)

class TestSectionFinder(unittest.TestCase):
    def test_getSections(self):
        '''Test SectionFinder'''
        # Divert subprocess.Popen
        subprocess_popen = subprocess.Popen
        subprocess.Popen = SubprocessPopen(self)
        config.EXPAND_LIBS_ORDER_STYLE = 'linkerscript'
        config.OBJ_SUFFIX = '.o'
        config.LIB_SUFFIX = '.a'
        finder = SectionFinder(['foo.o', 'bar.o'])
        self.assertEqual(finder.getSections('foobar'), [])
        self.assertEqual(finder.getSections('_Z6barbazv'), ['.text.hot._Z6barbazv'])
        self.assertEqual(finder.getSections('_Z6foobarv'), ['.text._Z6foobarv', '.text._ZThn4_6foobarv'])
        self.assertEqual(finder.getSections('_ZThn4_6foobarv'), ['.text._Z6foobarv', '.text._ZThn4_6foobarv'])
        subprocess.Popen = subprocess_popen

class TestSymbolOrder(unittest.TestCase):
    def test_getOrderedSections(self):
        '''Test ExpandMoreArgs' _getOrderedSections'''
        # Divert subprocess.Popen
        subprocess_popen = subprocess.Popen
        subprocess.Popen = SubprocessPopen(self)
        config.EXPAND_LIBS_ORDER_STYLE = 'linkerscript'
        config.OBJ_SUFFIX = '.o'
        config.LIB_SUFFIX = '.a'
        config.LD_PRINT_ICF_SECTIONS = ''
        args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
        self.assertEqual(args._getOrderedSections(['_Z6foobarv', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hot._Z6barbazv'])
        self.assertEqual(args._getOrderedSections(['_ZThn4_6foobarv', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hot._Z6barbazv'])
        subprocess.Popen = subprocess_popen

    def test_getFoldedSections(self):
        '''Test ExpandMoreArgs' _getFoldedSections'''
        # Divert subprocess.Popen
        subprocess_popen = subprocess.Popen
        subprocess.Popen = SubprocessPopen(self)
        config.LD_PRINT_ICF_SECTIONS = '-Wl,--print-icf-sections'
        args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
        self.assertEqual(args._getFoldedSections(), {'.text.hello': ['.text.hi'], '.text.hi': ['.text.hello']})
        subprocess.Popen = subprocess_popen

    def test_getOrderedSectionsWithICF(self):
        '''Test ExpandMoreArgs' _getOrderedSections, with ICF'''
        # Divert subprocess.Popen
        subprocess_popen = subprocess.Popen
        subprocess.Popen = SubprocessPopen(self)
        config.EXPAND_LIBS_ORDER_STYLE = 'linkerscript'
        config.OBJ_SUFFIX = '.o'
        config.LIB_SUFFIX = '.a'
        config.LD_PRINT_ICF_SECTIONS = '-Wl,--print-icf-sections'
        args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
        self.assertEqual(args._getOrderedSections(['hello', '_Z6barbazv']), ['.text.hello', '.text.hi', '.text.hot._Z6barbazv'])
        self.assertEqual(args._getOrderedSections(['_ZThn4_6foobarv', 'hi', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hi', '.text.hello', '.text.hot._Z6barbazv'])
        subprocess.Popen = subprocess_popen


if __name__ == '__main__':
    mozunit.main()
