# 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/.

from __future__ import print_function
import unittest

import os, sys, os.path, time, inspect
from filecmp import dircmp
from tempfile import mkdtemp
from shutil import rmtree, copy2
from StringIO import StringIO
from zipfile import ZipFile
import mozunit

from mozbuild.jar import JarMaker


if sys.platform == "win32":
    import ctypes
    from ctypes import POINTER, WinError
    DWORD = ctypes.c_ulong
    LPDWORD = POINTER(DWORD)
    HANDLE = ctypes.c_void_p
    GENERIC_READ = 0x80000000
    FILE_SHARE_READ = 0x00000001
    OPEN_EXISTING = 3
    MAX_PATH = 260

    class FILETIME(ctypes.Structure):
        _fields_ = [("dwLowDateTime", DWORD),
                    ("dwHighDateTime", DWORD)]

    class BY_HANDLE_FILE_INFORMATION(ctypes.Structure):
        _fields_ = [("dwFileAttributes", DWORD),
                    ("ftCreationTime", FILETIME),
                    ("ftLastAccessTime", FILETIME),
                    ("ftLastWriteTime", FILETIME),
                    ("dwVolumeSerialNumber", DWORD),
                    ("nFileSizeHigh", DWORD),
                    ("nFileSizeLow", DWORD),
                    ("nNumberOfLinks", DWORD),
                    ("nFileIndexHigh", DWORD),
                    ("nFileIndexLow", DWORD)]

    # http://msdn.microsoft.com/en-us/library/aa363858
    CreateFile = ctypes.windll.kernel32.CreateFileA
    CreateFile.argtypes = [ctypes.c_char_p, DWORD, DWORD, ctypes.c_void_p,
                           DWORD, DWORD, HANDLE]
    CreateFile.restype = HANDLE

    # http://msdn.microsoft.com/en-us/library/aa364952
    GetFileInformationByHandle = ctypes.windll.kernel32.GetFileInformationByHandle
    GetFileInformationByHandle.argtypes = [HANDLE, POINTER(BY_HANDLE_FILE_INFORMATION)]
    GetFileInformationByHandle.restype = ctypes.c_int

    # http://msdn.microsoft.com/en-us/library/aa364996
    GetVolumePathName = ctypes.windll.kernel32.GetVolumePathNameA
    GetVolumePathName.argtypes = [ctypes.c_char_p, ctypes.c_char_p, DWORD]
    GetVolumePathName.restype = ctypes.c_int

    # http://msdn.microsoft.com/en-us/library/aa364993
    GetVolumeInformation = ctypes.windll.kernel32.GetVolumeInformationA
    GetVolumeInformation.argtypes = [ctypes.c_char_p, ctypes.c_char_p, DWORD,
                                     LPDWORD, LPDWORD, LPDWORD, ctypes.c_char_p,
                                     DWORD]
    GetVolumeInformation.restype = ctypes.c_int

def symlinks_supported(path):
    if sys.platform == "win32":
        # Add 1 for a trailing backslash if necessary, and 1 for the terminating
        # null character.
        volpath = ctypes.create_string_buffer(len(path) + 2)
        rv = GetVolumePathName(path, volpath, len(volpath))
        if rv == 0:
            raise WinError()

        fsname = ctypes.create_string_buffer(MAX_PATH + 1)
        rv = GetVolumeInformation(volpath, None, 0, None, None, None, fsname,
                                  len(fsname))
        if rv == 0:
            raise WinError()

        # Return true only if the fsname is NTFS
        return fsname.value == "NTFS"
    else:
        return True

def _getfileinfo(path):
    """Return information for the given file. This only works on Windows."""
    fh = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, None, OPEN_EXISTING, 0, None)
    if fh is None:
        raise WinError()
    info = BY_HANDLE_FILE_INFORMATION()
    rv = GetFileInformationByHandle(fh, info)
    if rv == 0:
        raise WinError()
    return info

def is_symlink_to(dest, src):
    if sys.platform == "win32":
        # Check if both are on the same volume and have the same file ID
        destinfo = _getfileinfo(dest)
        srcinfo = _getfileinfo(src)
        return (destinfo.dwVolumeSerialNumber == srcinfo.dwVolumeSerialNumber and
                destinfo.nFileIndexHigh == srcinfo.nFileIndexHigh and
                destinfo.nFileIndexLow == srcinfo.nFileIndexLow)
    else:
        # Read the link and check if it is correct
        if not os.path.islink(dest):
            return False
        target = os.path.abspath(os.readlink(dest))
        abssrc = os.path.abspath(src)
        return target == abssrc

class _TreeDiff(dircmp):
    """Helper to report rich results on difference between two directories.
    """
    def _fillDiff(self, dc, rv, basepath="{0}"):
        rv['right_only'] += map(lambda l: basepath.format(l), dc.right_only)
        rv['left_only'] += map(lambda l: basepath.format(l), dc.left_only)
        rv['diff_files'] += map(lambda l: basepath.format(l), dc.diff_files)
        rv['funny'] += map(lambda l: basepath.format(l), dc.common_funny)
        rv['funny'] += map(lambda l: basepath.format(l), dc.funny_files)
        for subdir, _dc in dc.subdirs.iteritems():
            self._fillDiff(_dc, rv, basepath.format(subdir + "/{0}"))
    def allResults(self, left, right):
        rv = {'right_only':[], 'left_only':[],
              'diff_files':[], 'funny': []}
        self._fillDiff(self, rv)
        chunks = []
        if rv['right_only']:
            chunks.append('{0} only in {1}'.format(', '.join(rv['right_only']),
                                                   right))
        if rv['left_only']:
            chunks.append('{0} only in {1}'.format(', '.join(rv['left_only']),
                                                   left))
        if rv['diff_files']:
            chunks.append('{0} differ'.format(', '.join(rv['diff_files'])))
        if rv['funny']:
            chunks.append("{0} don't compare".format(', '.join(rv['funny'])))
        return '; '.join(chunks)

class TestJarMaker(unittest.TestCase):
    """
    Unit tests for JarMaker.py
    """
    debug = False # set to True to debug failing tests on disk
    def setUp(self):
        self.tmpdir = mkdtemp()
        self.srcdir = os.path.join(self.tmpdir, 'src')
        os.mkdir(self.srcdir)
        self.builddir = os.path.join(self.tmpdir, 'build')
        os.mkdir(self.builddir)
        self.refdir = os.path.join(self.tmpdir, 'ref')
        os.mkdir(self.refdir)
        self.stagedir = os.path.join(self.tmpdir, 'stage')
        os.mkdir(self.stagedir)

    def tearDown(self):
        if self.debug:
            print(self.tmpdir)
        elif sys.platform != "win32":
            # can't clean up on windows
            rmtree(self.tmpdir)

    def _jar_and_compare(self, infile, **kwargs):
        jm = JarMaker(outputFormat='jar')
        if 'topsourcedir' not in kwargs:
            kwargs['topsourcedir'] = self.srcdir
        for attr in ('topsourcedir', 'sourcedirs'):
            if attr in kwargs:
                setattr(jm, attr, kwargs[attr])
        jm.makeJar(infile, self.builddir)
        cwd = os.getcwd()
        os.chdir(self.builddir)
        try:
            # expand build to stage
            for path, dirs, files in os.walk('.'):
                stagedir = os.path.join(self.stagedir, path)
                if not os.path.isdir(stagedir):
                    os.mkdir(stagedir)
                for file in files:
                    if file.endswith('.jar'):
                        # expand jar
                        stagepath = os.path.join(stagedir, file)
                        os.mkdir(stagepath)
                        zf = ZipFile(os.path.join(path, file))
                        # extractall is only in 2.6, do this manually :-(
                        for entry_name in zf.namelist():
                            segs = entry_name.split('/')
                            fname = segs.pop()
                            dname = os.path.join(stagepath, *segs)
                            if not os.path.isdir(dname):
                                os.makedirs(dname)
                            if not fname:
                                # directory, we're done
                                continue
                            _c = zf.read(entry_name)
                            open(os.path.join(dname, fname), 'wb').write(_c)
                        zf.close()
                    else:
                        copy2(os.path.join(path, file), stagedir)
            # compare both dirs
            os.chdir('..')
            td = _TreeDiff('ref', 'stage')
            return td.allResults('reference', 'build')
        finally:
            os.chdir(cwd)

    def _create_simple_setup(self):
        # create src content
        jarf = open(os.path.join(self.srcdir, 'jar.mn'), 'w')
        jarf.write('''test.jar:
 dir/foo (bar)
''')
        jarf.close()
        open(os.path.join(self.srcdir,'bar'),'w').write('content\n')
        # create reference
        refpath = os.path.join(self.refdir, 'chrome', 'test.jar', 'dir')
        os.makedirs(refpath)
        open(os.path.join(refpath, 'foo'), 'w').write('content\n')        

    def test_a_simple_jar(self):
        '''Test a simple jar.mn'''
        self._create_simple_setup()
        # call JarMaker
        rv = self._jar_and_compare(os.path.join(self.srcdir,'jar.mn'),
                                   sourcedirs = [self.srcdir])
        self.assertTrue(not rv, rv)

    def test_a_simple_symlink(self):
        '''Test a simple jar.mn with a symlink'''
        if not symlinks_supported(self.srcdir):
            raise unittest.SkipTest('symlinks not supported')

        self._create_simple_setup()
        jm = JarMaker(outputFormat='symlink')
        jm.sourcedirs = [self.srcdir]
        jm.topsourcedir = self.srcdir
        jm.makeJar(os.path.join(self.srcdir,'jar.mn'), self.builddir)
        # All we do is check that srcdir/bar points to builddir/chrome/test/dir/foo
        srcbar = os.path.join(self.srcdir, 'bar')
        destfoo = os.path.join(self.builddir, 'chrome', 'test', 'dir', 'foo')
        self.assertTrue(is_symlink_to(destfoo, srcbar),
                        "{0} is not a symlink to {1}".format(destfoo, srcbar))

    def _create_wildcard_setup(self):
        # create src content
        jarf = open(os.path.join(self.srcdir, 'jar.mn'), 'w')
        jarf.write('''test.jar:
 dir/bar (*.js)
 dir/hoge (qux/*)
''')
        jarf.close()
        open(os.path.join(self.srcdir,'foo.js'),'w').write('foo.js\n')
        open(os.path.join(self.srcdir,'bar.js'),'w').write('bar.js\n')
        os.makedirs(os.path.join(self.srcdir, 'qux', 'foo'))
        open(os.path.join(self.srcdir,'qux', 'foo', '1'),'w').write('1\n')
        open(os.path.join(self.srcdir,'qux', 'foo', '2'),'w').write('2\n')
        open(os.path.join(self.srcdir,'qux', 'baz'),'w').write('baz\n')
        # create reference
        refpath = os.path.join(self.refdir, 'chrome', 'test.jar', 'dir')
        os.makedirs(os.path.join(refpath, 'bar'))
        os.makedirs(os.path.join(refpath, 'hoge', 'foo'))
        open(os.path.join(refpath, 'bar', 'foo.js'), 'w').write('foo.js\n')
        open(os.path.join(refpath, 'bar', 'bar.js'), 'w').write('bar.js\n')
        open(os.path.join(refpath, 'hoge', 'foo', '1'), 'w').write('1\n')
        open(os.path.join(refpath, 'hoge', 'foo', '2'), 'w').write('2\n')
        open(os.path.join(refpath, 'hoge', 'baz'), 'w').write('baz\n')

    def test_a_wildcard_jar(self):
        '''Test a wildcard in jar.mn'''
        self._create_wildcard_setup()
        # call JarMaker
        rv = self._jar_and_compare(os.path.join(self.srcdir,'jar.mn'),
                                   sourcedirs = [self.srcdir])
        self.assertTrue(not rv, rv)

    def test_a_wildcard_symlink(self):
        '''Test a wildcard in jar.mn with symlinks'''
        if not symlinks_supported(self.srcdir):
            raise unittest.SkipTest('symlinks not supported')

        self._create_wildcard_setup()
        jm = JarMaker(outputFormat='symlink')
        jm.sourcedirs = [self.srcdir]
        jm.topsourcedir = self.srcdir
        jm.makeJar(os.path.join(self.srcdir,'jar.mn'), self.builddir)

        expected_symlinks = {
            ('bar', 'foo.js'): ('foo.js',),
            ('bar', 'bar.js'): ('bar.js',),
            ('hoge', 'foo', '1'): ('qux', 'foo', '1'),
            ('hoge', 'foo', '2'): ('qux', 'foo', '2'),
            ('hoge', 'baz'): ('qux', 'baz'),
        }
        for dest, src in expected_symlinks.iteritems():
            srcpath = os.path.join(self.srcdir, *src)
            destpath = os.path.join(self.builddir, 'chrome', 'test', 'dir',
                                    *dest)
            self.assertTrue(is_symlink_to(destpath, srcpath),
                            "{0} is not a symlink to {1}".format(destpath,
                                                                 srcpath))


class Test_relativesrcdir(unittest.TestCase):
    def setUp(self):
        self.jm = JarMaker()
        self.jm.topsourcedir = '/TOPSOURCEDIR'
        self.jm.relativesrcdir = 'browser/locales'
        self.fake_empty_file = StringIO()
        self.fake_empty_file.name = 'fake_empty_file'
    def tearDown(self):
        del self.jm
        del self.fake_empty_file
    def test_en_US(self):
        jm = self.jm
        jm.makeJar(self.fake_empty_file, '/NO_OUTPUT_REQUIRED')
        self.assertEquals(jm.localedirs,
                          [
                            os.path.join(os.path.abspath('/TOPSOURCEDIR'),
                                         'browser/locales', 'en-US')
                            ])
    def test_l10n_no_merge(self):
        jm = self.jm
        jm.l10nbase = '/L10N_BASE'
        jm.makeJar(self.fake_empty_file, '/NO_OUTPUT_REQUIRED')
        self.assertEquals(jm.localedirs, [os.path.join('/L10N_BASE', 'browser')])
    def test_l10n_merge(self):
        jm = self.jm
        jm.l10nbase = '/L10N_BASE'
        jm.l10nmerge = '/L10N_MERGE'
        jm.makeJar(self.fake_empty_file, '/NO_OUTPUT_REQUIRED')
        self.assertEquals(jm.localedirs,
                          [os.path.join('/L10N_MERGE', 'browser'),
                           os.path.join('/L10N_BASE', 'browser'),
                           os.path.join(os.path.abspath('/TOPSOURCEDIR'),
                                        'browser/locales', 'en-US')
                           ])
    def test_override(self):
        jm = self.jm
        jm.outputFormat = 'flat'  # doesn't touch chrome dir without files
        jarcontents = StringIO('''en-US.jar:
relativesrcdir dom/locales:
''')
        jarcontents.name = 'override.mn'
        jm.makeJar(jarcontents, '/NO_OUTPUT_REQUIRED')
        self.assertEquals(jm.localedirs,
                          [
                            os.path.join(os.path.abspath('/TOPSOURCEDIR'),
                                         'dom/locales', 'en-US')
                            ])
    def test_override_l10n(self):
        jm = self.jm
        jm.l10nbase = '/L10N_BASE'
        jm.outputFormat = 'flat'  # doesn't touch chrome dir without files
        jarcontents = StringIO('''en-US.jar:
relativesrcdir dom/locales:
''')
        jarcontents.name = 'override.mn'
        jm.makeJar(jarcontents, '/NO_OUTPUT_REQUIRED')
        self.assertEquals(jm.localedirs, [os.path.join('/L10N_BASE', 'dom')])


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