#!/usr/bin/env python

# Copyright 2016 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import sys
import unittest
import re

# hack import paths to pick up extra code
sys.path.insert(0, os.path.abspath('tools/run_tests/'))
from run_tests_matrix import _create_test_jobs, _create_portability_test_jobs
import python_utils.filter_pull_request_tests as filter_pull_request_tests

_LIST_OF_LANGUAGE_LABELS = [
    'c', 'c++', 'csharp', 'grpc-node', 'objc', 'php', 'php7', 'python', 'ruby'
]
_LIST_OF_PLATFORM_LABELS = ['linux', 'macos', 'windows']


class TestFilteringTest(unittest.TestCase):

    def generate_all_tests(self):
        all_jobs = _create_test_jobs() + _create_portability_test_jobs()
        self.assertIsNotNone(all_jobs)
        return all_jobs

    def test_filtering(self, changed_files=[], labels=_LIST_OF_LANGUAGE_LABELS):
        """
    Default args should filter no tests because changed_files is empty and
    default labels should be able to match all jobs
    :param changed_files: mock list of changed_files from pull request
    :param labels: list of job labels that should be skipped
    """
        all_jobs = self.generate_all_tests()

        # Replacing _get_changed_files function to allow specifying changed files in filter_tests function
        def _get_changed_files(foo):
            return changed_files

        filter_pull_request_tests._get_changed_files = _get_changed_files
        print()
        filtered_jobs = filter_pull_request_tests.filter_tests(all_jobs, "test")

        # Make sure sanity tests aren't being filtered out
        sanity_tests_in_all_jobs = 0
        sanity_tests_in_filtered_jobs = 0
        for job in all_jobs:
            if "sanity" in job.labels:
                sanity_tests_in_all_jobs += 1
        all_jobs = [job for job in all_jobs if "sanity" not in job.labels]
        for job in filtered_jobs:
            if "sanity" in job.labels:
                sanity_tests_in_filtered_jobs += 1
        filtered_jobs = [
            job for job in filtered_jobs if "sanity" not in job.labels
        ]
        self.assertEquals(sanity_tests_in_all_jobs,
                          sanity_tests_in_filtered_jobs)

        for label in labels:
            for job in filtered_jobs:
                self.assertNotIn(label, job.labels)

        jobs_matching_labels = 0
        for label in labels:
            for job in all_jobs:
                if (label in job.labels):
                    jobs_matching_labels += 1
        self.assertEquals(
            len(filtered_jobs),
            len(all_jobs) - jobs_matching_labels)

    def test_individual_language_filters(self):
        # Changing unlisted file should trigger all languages
        self.test_filtering(['ffffoo/bar.baz'], [_LIST_OF_LANGUAGE_LABELS])
        # Changing core should trigger all tests
        self.test_filtering(['src/core/foo.bar'], [_LIST_OF_LANGUAGE_LABELS])
        # Testing individual languages
        self.test_filtering(['test/core/foo.bar'], [
            label for label in _LIST_OF_LANGUAGE_LABELS
            if label not in filter_pull_request_tests._CORE_TEST_SUITE.labels +
            filter_pull_request_tests._CPP_TEST_SUITE.labels
        ])
        self.test_filtering(['src/cpp/foo.bar'], [
            label for label in _LIST_OF_LANGUAGE_LABELS
            if label not in filter_pull_request_tests._CPP_TEST_SUITE.labels
        ])
        self.test_filtering(['src/csharp/foo.bar'], [
            label for label in _LIST_OF_LANGUAGE_LABELS
            if label not in filter_pull_request_tests._CSHARP_TEST_SUITE.labels
        ])
        self.test_filtering(['src/objective-c/foo.bar'], [
            label for label in _LIST_OF_LANGUAGE_LABELS
            if label not in filter_pull_request_tests._OBJC_TEST_SUITE.labels
        ])
        self.test_filtering(['src/php/foo.bar'], [
            label for label in _LIST_OF_LANGUAGE_LABELS
            if label not in filter_pull_request_tests._PHP_TEST_SUITE.labels
        ])
        self.test_filtering(['src/python/foo.bar'], [
            label for label in _LIST_OF_LANGUAGE_LABELS
            if label not in filter_pull_request_tests._PYTHON_TEST_SUITE.labels
        ])
        self.test_filtering(['src/ruby/foo.bar'], [
            label for label in _LIST_OF_LANGUAGE_LABELS
            if label not in filter_pull_request_tests._RUBY_TEST_SUITE.labels
        ])

    def test_combined_language_filters(self):
        self.test_filtering(['src/cpp/foo.bar', 'test/core/foo.bar'], [
            label for label in _LIST_OF_LANGUAGE_LABELS
            if label not in filter_pull_request_tests._CPP_TEST_SUITE.labels and
            label not in filter_pull_request_tests._CORE_TEST_SUITE.labels
        ])
        self.test_filtering(['src/cpp/foo.bar', "src/csharp/foo.bar"], [
            label for label in _LIST_OF_LANGUAGE_LABELS
            if label not in filter_pull_request_tests._CPP_TEST_SUITE.labels and
            label not in filter_pull_request_tests._CSHARP_TEST_SUITE.labels
        ])
        self.test_filtering([
            'src/objective-c/foo.bar', 'src/php/foo.bar', "src/python/foo.bar",
            "src/ruby/foo.bar"
        ], [
            label for label in _LIST_OF_LANGUAGE_LABELS
            if label not in filter_pull_request_tests._OBJC_TEST_SUITE.labels
            and label not in filter_pull_request_tests._PHP_TEST_SUITE.labels
            and label not in filter_pull_request_tests._PYTHON_TEST_SUITE.labels
            and label not in filter_pull_request_tests._RUBY_TEST_SUITE.labels
        ])

    def test_platform_filter(self):
        self.test_filtering(['vsprojects/foo.bar'], [
            label for label in _LIST_OF_PLATFORM_LABELS
            if label not in filter_pull_request_tests._WINDOWS_TEST_SUITE.labels
        ])

    def test_whitelist(self):
        whitelist = filter_pull_request_tests._WHITELIST_DICT
        files_that_should_trigger_all_tests = [
            'src/core/foo.bar', 'some_file_not_on_the_white_list', 'BUILD',
            'etc/roots.pem', 'Makefile', 'tools/foo'
        ]
        for key in whitelist.keys():
            for file_name in files_that_should_trigger_all_tests:
                self.assertFalse(re.match(key, file_name))


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