# -*- coding: utf-8 -*-
'''
    This module implements unit tests of the submission validation.
'''

import os
import sys
import glob
import unittest

from test import test_cli


class TestValidateSystem(unittest.TestCase):
    """
    Test the actev validate-system CLI call, using valid and invalid
    directories
    """

    def setUp(self):

        current_path = os.path.abspath(__file__)
        self.test_dir_path = os.path.dirname(current_path)

        self.test_examples_path = os.path.join(
            self.test_dir_path, 'validate_system/validate_container_output')
        self.system_outputs_dir = os.path.join(
            self.test_dir_path, '../diva_evaluation_cli/container_output')
        self.old_system_outputs_dir = self.system_outputs_dir + '_tmp'

        # Move existing system outputs to perform test
        os.renames(self.system_outputs_dir, self.old_system_outputs_dir)
        os.makedirs(self.system_outputs_dir)

        valid_test_examples_dirs = os.listdir(os.path.join(
            self.test_examples_path, 'valid'))
        self.valid_test_examples = [os.path.join(
            self.test_examples_path, 'valid',
            os.path.basename(subdir)) for subdir in valid_test_examples_dirs]

        invalid_test_examples_dirs = os.listdir(os.path.join(
            self.test_examples_path, 'invalid'))
        self.invalid_test_examples = [os.path.join(
            self.test_examples_path, 'invalid',
            os.path.basename(subdir)) for subdir in invalid_test_examples_dirs]

    def tearDown(self):
        # Remove all symbolic links
        test_examples = self.valid_test_examples + self.invalid_test_examples

        for test_example_dir in test_examples:
            link_path = os.path.join(
                self.system_outputs_dir, os.path.basename(test_example_dir))
            if os.path.islink(link_path):
                os.unlink(link_path)

        # Move back previous system outputs
        os.renames(self.old_system_outputs_dir, self.system_outputs_dir)

    def test_valid_container_outputs(self):

        assert len(self.valid_test_examples) > 0

        for test_example_dir in self.valid_test_examples:
            new_system_output = os.path.join(
                self.system_outputs_dir, os.path.basename(test_example_dir))
            print('Linking {} to {}'.format(
                test_example_dir, new_system_output))
            os.symlink(test_example_dir, new_system_output)
        sys.argv[1:] = ['validate-system', '--strict']
        test_cli("Strict validator failed on valid submission {}".format(
            test_example_dir))

    def test_invalid_container_outputs(self):

        assert len(self.invalid_test_examples) > 0

        for test_example_dir in self.invalid_test_examples:
            new_system_output = os.path.join(
                self.system_outputs_dir, os.path.basename(test_example_dir))
            print('Linking {} to {}'.format(
                test_example_dir, new_system_output))
            os.symlink(test_example_dir, new_system_output)

            # Test the validator in a strict mode
            sys.argv[1:] = ['validate-system', '--strict']
            with self.assertRaises(SystemExit):
                test_cli("Validator succedded on invalid system output \
                    {}".format(test_example_dir))

            # Test the validator in a non strict mode
            sys.argv[1:] = ['validate-system']
            test_cli("Non strict validator produced an error on invalid \
                submission {}".format(test_example_dir))


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