#!/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 shutil
import tempfile
import unittest

from manifestparser import convert, ManifestParser

class TestSymlinkConversion(unittest.TestCase):
    """
    test conversion of a directory tree with symlinks to a manifest structure
    """

    def create_stub(self, directory=None):
        """stub out a directory with files in it"""

        files = ('foo', 'bar', 'fleem')
        if directory is None:
            directory = tempfile.mkdtemp()
        for i in files:
            file(os.path.join(directory, i), 'w').write(i)
        subdir = os.path.join(directory, 'subdir')
        os.mkdir(subdir)
        file(os.path.join(subdir, 'subfile'), 'w').write('baz')
        return directory

    def test_relpath(self):
        """test convert `relative_to` functionality"""

        oldcwd = os.getcwd()
        stub = self.create_stub()
        try:
            # subdir with in-memory manifest
            files = ['../bar', '../fleem', '../foo', 'subfile']
            subdir = os.path.join(stub, 'subdir')
            os.chdir(subdir)
            parser = convert([stub], relative_to='.')
            self.assertEqual([i['name'] for i in parser.tests],
                             files)
        except:
            raise
        finally:
            shutil.rmtree(stub)
            os.chdir(oldcwd)

    @unittest.skipIf(not hasattr(os, 'symlink'),
                     "symlinks unavailable on this platform")
    def test_relpath_symlink(self):
        """
        Ensure `relative_to` works in a symlink.
        Not available on windows.
        """

        oldcwd = os.getcwd()
        workspace = tempfile.mkdtemp()
        try:
            tmpdir = os.path.join(workspace, 'directory')
            os.makedirs(tmpdir)
            linkdir = os.path.join(workspace, 'link')
            os.symlink(tmpdir, linkdir)
            self.create_stub(tmpdir)

            # subdir with in-memory manifest
            files = ['../bar', '../fleem', '../foo', 'subfile']
            subdir = os.path.join(linkdir, 'subdir')
            os.chdir(os.path.realpath(subdir))
            for directory in (tmpdir, linkdir):
                parser = convert([directory], relative_to='.')
                self.assertEqual([i['name'] for i in parser.tests],
                                 files)
        finally:
            shutil.rmtree(workspace)
            os.chdir(oldcwd)

        # a more complicated example
        oldcwd = os.getcwd()
        workspace = tempfile.mkdtemp()
        try:
            tmpdir = os.path.join(workspace, 'directory')
            os.makedirs(tmpdir)
            linkdir = os.path.join(workspace, 'link')
            os.symlink(tmpdir, linkdir)
            self.create_stub(tmpdir)
            files = ['../bar', '../fleem', '../foo', 'subfile']
            subdir = os.path.join(linkdir, 'subdir')
            subsubdir = os.path.join(subdir, 'sub')
            os.makedirs(subsubdir)
            linksubdir = os.path.join(linkdir, 'linky')
            linksubsubdir = os.path.join(subsubdir, 'linky')
            os.symlink(subdir, linksubdir)
            os.symlink(subdir, linksubsubdir)
            for dest in (subdir,):
                os.chdir(dest)
                for directory in (tmpdir, linkdir):
                    parser = convert([directory], relative_to='.')
                    self.assertEqual([i['name'] for i in parser.tests],
                                     files)
        finally:
            shutil.rmtree(workspace)
            os.chdir(oldcwd)

    @unittest.skipIf(not hasattr(os, 'symlink'),
                     "symlinks unavailable on this platform")
    def test_recursion_symlinks(self):
        workspace = tempfile.mkdtemp()
        self.addCleanup(shutil.rmtree, workspace)

        # create two dirs
        os.makedirs(os.path.join(workspace, 'dir1'))
        os.makedirs(os.path.join(workspace, 'dir2'))

        # create cyclical symlinks
        os.symlink(os.path.join('..', 'dir1'),
                   os.path.join(workspace, 'dir2', 'ldir1'))
        os.symlink(os.path.join('..', 'dir2'),
                   os.path.join(workspace, 'dir1', 'ldir2'))

        # create one file in each dir
        open(os.path.join(workspace, 'dir1', 'f1.txt'), 'a').close()
        open(os.path.join(workspace, 'dir1', 'ldir2', 'f2.txt'), 'a').close()

        data = []
        def callback(rootdirectory, directory, subdirs, files):
            for f in files:
                data.append(f)

        ManifestParser._walk_directories([workspace], callback)
        self.assertEqual(sorted(data), ['f1.txt', 'f2.txt'])


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