# Copyright 2020 The Pigweed 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
#
#     https://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.
#
"""Unit tests for owners_checks.py."""
from pathlib import Path
import tempfile
from typing import Iterable, Sequence, Tuple
import unittest
from unittest import mock
from pw_presubmit import owners_checks

# ===== Test data =====

bad_duplicate = """\
# Should raise OwnersDuplicateError.
set noparent

file:/foo/OWNERZ
file:../OWNERS
file:../OWNERS
test1@example.com
#Test 2 comment
test2@example.com
"""

bad_duplicate_user = """\
# Should raise OwnersDuplicateError.
set noparent

file:/foo/OWNERZ
file:../OWNERS

*
test1@example.com
#Test 2 comment
test2@example.com
                        test1@example.com
"""

bad_duplicate_wildcard = """\
# Should raise OwnersDuplicateError.
set noparent
*
file:/foo/OWNERZ
file:../OWNERS
test1@example.com
#Test 2 comment
test2@example.com
*
"""

bad_email = """\
# Should raise OwnersInvalidLineError.
set noparent
*
file:/foo/OWNERZ
file:../OWNERS
test1example.com
#Test 2 comment
test2@example.com
*
"""
bad_grant_combo = """\
# Should raise OwnersUserGrantError.

file:/foo/OWNERZ
file:../OWNERS

test1@example.com
#Test noparent comment
set noparent
test2@example.com

*
"""

bad_ordering1 = """\
# Tests formatter reorders groupings of lines into the right order.
file:/foo/OWNERZ
file:bar/OWNERZ

test1@example.com
#Test noparent comment
set noparent
test2@example.com
"""

bad_ordering1_fixed = """\
#Test noparent comment
set noparent

# Tests formatter reorders groupings of lines into the right order.
file:/foo/OWNERZ
file:bar/OWNERZ

test1@example.com
test2@example.com
"""

bad_prohibited1 = """\
# Should raise OwnersProhibitedError.
set noparent

file:/foo/OWNERZ
file:../OWNERS

test1@example.com
#Test 2 comment
test2@example.com

include file1.txt

per-file foo.txt=test3@example.com
"""

bad_moving_comments = """\
# Test comments move with the rule that follows them.
test2@example.com
test1@example.com

# foo comment
file:/foo/OWNERZ
# .. comment
file:../OWNERS

set noparent
"""
bad_moving_comments_fixed = """\
set noparent

# .. comment
file:../OWNERS
# foo comment
file:/foo/OWNERZ

test1@example.com
# Test comments move with the rule that follows them.
test2@example.com
"""

bad_whitespace = """\
 set   noparent



file:/foo/OWNERZ

  file:../OWNERS

test1@example.com
#Test 2    comment
    test2@example.com

"""

bad_whitespace_fixed = """\
set noparent

file:../OWNERS
file:/foo/OWNERZ

test1@example.com
#Test 2    comment
test2@example.com
"""

no_dependencies = """\
# Test no imports are found when there are none.
set noparent

test1@example.com
#Test 2 comment
test2@example.com
"""

has_dependencies_file = """\
# Test if owners checks examine file: imports.
set noparent

file:foo_owners
file:bar_owners

test1@example.com
#Test 2 comment
test2@example.com
"""

has_dependencies_perfile = """\
# Test if owners checks examine per-file imports.
set noparent

test1@example.com
#Test 2 comment
test2@example.com

per-file *.txt=file:foo_owners
per-file *.md=example.google.com
"""

has_dependencies_include = """\
# Test if owners checks examine per-file imports.
set noparent

test1@example.com
#Test 2 comment
test2@example.com

per-file *.txt=file:foo_owners
per-file *.md=example.google.com
"""

dependencies_paths_relative = """\
set noparent

include foo/bar/../include_owners

file:foo/bar/../file_owners

*

per-file *.txt=file:foo/bar/../perfile_owners
"""

dependencies_paths_absolute = """\
set noparent

include /test/include_owners

file:/test/file_owners

*

per-file *.txt=file:/test/perfile_owners
"""

good1 = """\
# Checks should fine this formatted correctly
set noparent

include good1_include

file:good1_file

test1@example.com
#Test 2 comment
test2@example.com #{LAST_RESORT_SUGGESTION}
# LAST LINE
"""

good1_include = """\
test1@example.comom
"""

good1_file = """\
# Checks should fine this formatted correctly.
test1@example.com
"""

foo_owners = """\
test1@example.com
"""

bar_owners = """\
test1@example.com
"""

BAD_TEST_FILES = (
    ("bad_duplicate", owners_checks.OwnersDuplicateError),
    ("bad_duplicate_user", owners_checks.OwnersDuplicateError),
    ("bad_duplicate_wildcard", owners_checks.OwnersDuplicateError),
    ("bad_email", owners_checks.OwnersInvalidLineError),
    ("bad_grant_combo", owners_checks.OwnersUserGrantError),
    ("bad_ordering1", owners_checks.OwnersStyleError),
    ("bad_prohibited1", owners_checks.OwnersProhibitedError),
)

STYLING_CHECKS = (
    ("bad_moving_comments", "bad_moving_comments_fixed"),
    ("bad_ordering1", "bad_ordering1_fixed"),
    ("bad_whitespace", "bad_whitespace_fixed"),
)

DEPENDENCY_TEST_CASES: Iterable[Tuple[str, Iterable[str]]] = (
    ("no_dependencies", tuple()),
    ("has_dependencies_file", ("foo_owners", "bar_owners")),
    ("has_dependencies_perfile", ("foo_owners", )),
    ("has_dependencies_include", ("foo_owners", )),
)

DEPENDENCY_PATH_TEST_CASES: Iterable[str] = (
    "dependencies_paths_relative",
    "dependencies_paths_absolute",
)

GOOD_TEST_CASES = (("good1", "good1_include", "good1_file"), )


# ===== Unit Tests =====
class TestOwnersChecks(unittest.TestCase):
    """Unittest class for owners_checks.py."""

    maxDiff = 2000

    @staticmethod
    def _create_temp_files(
            temp_dir: str, file_list: Sequence[Tuple[str,
                                                     str]]) -> Sequence[Path]:
        real_files = []
        temp_dir_path = Path(temp_dir)
        for name, contents in file_list:
            file_path = temp_dir_path / name
            file_path.write_text(contents)
            real_files.append(file_path)
        return real_files

    def test_bad_files(self):
        # First test_file is the "primary" owners file followed by any needed
        # "secondary" owners.
        for test_file, expected_exception in BAD_TEST_FILES:
            with self.subTest(i=test_file), tempfile.TemporaryDirectory(
            ) as temp_dir, self.assertRaises(expected_exception):
                file_contents = globals()[test_file]
                primary_file = self._create_temp_files(
                    temp_dir=temp_dir,
                    file_list=((test_file, file_contents), ))[0]
                owners_file = owners_checks.OwnersFile(primary_file)
                owners_file.look_for_owners_errors()
                owners_file.check_style()

    def test_good(self):
        # First test_file is the "primary" owners file followed by any needed
        # "secondary" owners.
        for test_files in GOOD_TEST_CASES:
            with self.subTest(i=test_files[0]), tempfile.TemporaryDirectory(
            ) as temp_dir:
                files = [(file_name, globals()[file_name])
                         for file_name in test_files]
                primary_file = self._create_temp_files(temp_dir=temp_dir,
                                                       file_list=files)[0]
                self.assertDictEqual(
                    {}, owners_checks.run_owners_checks(primary_file))

    def test_style_proposals(self):
        for unstyled_file, styled_file in STYLING_CHECKS:
            with self.subTest(i=unstyled_file), tempfile.TemporaryDirectory(
            ) as temp_dir:
                unstyled_contents = globals()[unstyled_file]
                styled_contents = globals()[styled_file]
                unstyled_real_file = self._create_temp_files(
                    temp_dir=temp_dir,
                    file_list=((unstyled_file, unstyled_contents), ))[0]
                owners_file = owners_checks.OwnersFile(unstyled_real_file)
                formatted_content = "\n".join(owners_file.formatted_lines)
                self.assertEqual(styled_contents, formatted_content)

    def test_dependency_discovery(self):
        for file_under_test, expected_deps in DEPENDENCY_TEST_CASES:
            # During test make the test file directory the "git root"
            with tempfile.TemporaryDirectory() as temp_dir:
                temp_dir_path = Path(temp_dir).resolve()
                with self.subTest(i=file_under_test), mock.patch(
                        "pw_presubmit.owners_checks.git_repo.root",
                        return_value=temp_dir_path):
                    primary_file = (file_under_test,
                                    globals()[file_under_test])
                    deps_files = tuple(
                        (dep, (globals()[dep])) for dep in expected_deps)

                    primary_file = self._create_temp_files(
                        temp_dir=temp_dir, file_list=(primary_file, ))[0]
                    dep_files = self._create_temp_files(temp_dir=temp_dir,
                                                        file_list=deps_files)

                    owners_file = owners_checks.OwnersFile(primary_file)

                    # get_dependencies is expected to resolve() files
                    found_deps = owners_file.get_dependencies()
                    expected_deps_path = [path.resolve() for path in dep_files]
                    expected_deps_path.sort()
                    found_deps.sort()
                    self.assertListEqual(expected_deps_path, found_deps)

    def test_dependency_path_creation(self):
        """Confirm paths care constructed for absolute and relative paths."""
        for file_under_test in DEPENDENCY_PATH_TEST_CASES:
            # During test make the test file directory the "git root"
            with tempfile.TemporaryDirectory() as temp_dir:
                temp_dir_path = Path(temp_dir).resolve()
                with self.subTest(i=file_under_test), mock.patch(
                        "pw_presubmit.owners_checks.git_repo.root",
                        return_value=temp_dir_path):
                    owners_file_path = (temp_dir_path / "owners" /
                                        file_under_test)
                    owners_file_path.parent.mkdir(parents=True)
                    owners_file_path.write_text(globals()[file_under_test])
                    owners_file = owners_checks.OwnersFile(owners_file_path)

                    # get_dependencies is expected to resolve() files
                    found_deps = owners_file.get_dependencies()

                    if "absolute" in file_under_test:
                        # Absolute paths start with the git/project root
                        expected_prefix = temp_dir_path / "test"
                    else:
                        # Relative paths start with owners file dir
                        expected_prefix = owners_file_path.parent / "foo"

                    expected_deps_path = [
                        (expected_prefix / filename).resolve()
                        for filename in ("include_owners", "file_owners",
                                         "perfile_owners")
                    ]
                    expected_deps_path.sort()
                    found_deps.sort()
                    self.assertListEqual(expected_deps_path, found_deps)


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