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

import os, sys, glob
import unittest

from diva_evaluation_cli.bin.cli import cli_parser 


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']
        try:
            cli_parser()
        except Exception:
            self.fail("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):
                cli_parser()
                self.fail("Validator succedded on invalid system output {}".format(test_example_dir))

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


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