# Copyright 2021 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.
"""Tests for pw_build.create_python_tree"""

import io
import os
from pathlib import Path
import tempfile
from typing import List
import unittest

from parameterized import parameterized  # type: ignore

from pw_build.python_package import PythonPackage
from pw_build.create_python_tree import (
    build_python_tree,
    copy_extra_files,
    load_common_config,
    update_config_with_packages,
)
from pw_build.generate_python_package import PYPROJECT_FILE


def _setup_cfg(package_name: str, install_requires: str = '') -> str:
    return f'''
[metadata]
name = {package_name}
version = 0.0.1
author = Pigweed Authors
author_email = pigweed-developers@googlegroups.com
description = Pigweed swiss-army knife

[options]
packages = find:
zip_safe = False
{install_requires}

[options.package_data]
{package_name} =
    py.typed
    '''


def _create_fake_python_package(location: Path,
                                package_name: str,
                                files: List[str],
                                install_requires: str = '') -> None:
    for file in files:
        destination = location / file
        destination.parent.mkdir(parents=True, exist_ok=True)
        text = f'"""{package_name}"""'
        if str(destination).endswith('setup.cfg'):
            text = _setup_cfg(package_name, install_requires)
        elif str(destination).endswith('pyproject.toml'):
            # Make sure pyproject.toml file has valid syntax.
            text = PYPROJECT_FILE
        destination.write_text(text)


class TestCreatePythonTree(unittest.TestCase):
    """Integration tests for create_python_tree."""
    def setUp(self):
        self.maxDiff = None  # pylint: disable=invalid-name
        # Save the starting working directory for returning to later.
        self.start_dir = Path.cwd()
        # Create a temp out directory
        self.temp_dir = tempfile.TemporaryDirectory()

    def tearDown(self):
        # cd to the starting dir before cleaning up the temp out directory
        os.chdir(self.start_dir)
        # Delete the TemporaryDirectory
        self.temp_dir.cleanup()

    def _check_result_paths_equal(self, install_dir, expected_results) -> None:
        # Normalize path strings to posix before comparing.
        expected_paths = set(Path(p).as_posix() for p in expected_results)
        actual_paths = set(
            p.relative_to(install_dir).as_posix()
            for p in install_dir.glob('**/*') if p.is_file())
        self.assertEqual(expected_paths, actual_paths)

    def test_update_config_with_packages(self) -> None:
        """Test merging package setup.cfg files."""
        temp_root = Path(self.temp_dir.name)
        common_config = temp_root / 'common_setup.cfg'
        common_config.write_text('''
[metadata]
name = megapackage
version = 0.0.1
author = Pigweed Authors
author_email = pigweed-developers@googlegroups.com
description = Pigweed swiss-army knife

[options]
zip_safe = False

[options.package_data]
megapackage =
    py.typed
''')
        config = load_common_config(common_config=common_config,
                                    append_git_sha=False,
                                    append_date=False)
        config_metadata = dict(config['metadata'].items())
        self.assertIn('name', config_metadata)

        pkg1_root = temp_root / 'pkg1'
        pkg2_root = temp_root / 'pkg2'
        _create_fake_python_package(pkg1_root,
                                    'mars', [
                                        'planets/BUILD.mars_rocket',
                                        'planets/mars/__init__.py',
                                        'planets/mars/__main__.py',
                                        'planets/mars/moons/__init__.py',
                                        'planets/mars/moons/deimos.py',
                                        'planets/mars/moons/phobos.py',
                                        'planets/hohmann_transfer_test.py',
                                        'planets/pyproject.toml',
                                        'planets/setup.cfg',
                                    ],
                                    install_requires='''
install_requires =
        coloredlogs
        coverage
        cryptography
        graphlib-backport;python_version<'3.9'
        httpwatcher
''')

        os.chdir(pkg1_root)
        pkg1 = PythonPackage.from_dict(
            **{
                'generate_setup': {
                    'metadata': {
                        'name': 'mars',
                        'version': '0.0.1'
                    },
                },
                'inputs': [],
                'setup_sources': [
                    'planets/pyproject.toml',
                    'planets/setup.cfg',
                ],
                'sources': [
                    'planets/mars/__init__.py',
                    'planets/mars/__main__.py',
                    'planets/mars/moons/__init__.py',
                    'planets/mars/moons/deimos.py',
                    'planets/mars/moons/phobos.py',
                ],
                'tests': [
                    'planets/hohmann_transfer_test.py',
                ],
            })

        _create_fake_python_package(pkg2_root,
                                    'saturn', [
                                        'planets/BUILD.saturn_rocket',
                                        'planets/hohmann_transfer_test.py',
                                        'planets/pyproject.toml',
                                        'planets/saturn/__init__.py',
                                        'planets/saturn/__main__.py',
                                        'planets/saturn/misson.py',
                                        'planets/saturn/moons/__init__.py',
                                        'planets/saturn/moons/enceladus.py',
                                        'planets/saturn/moons/iapetus.py',
                                        'planets/saturn/moons/rhea.py',
                                        'planets/saturn/moons/titan.py',
                                        'planets/setup.cfg',
                                        'planets/setup.py',
                                    ],
                                    install_requires='''
install_requires =
        graphlib-backport;python_version<'3.9'
        httpwatcher
''')
        os.chdir(pkg2_root)
        pkg2 = PythonPackage.from_dict(
            **{
                'inputs': [],
                'setup_sources': [
                    'planets/pyproject.toml',
                    'planets/setup.cfg',
                    'planets/setup.py',
                ],
                'sources': [
                    'planets/saturn/__init__.py',
                    'planets/saturn/__main__.py',
                    'planets/saturn/misson.py',
                    'planets/saturn/moons/__init__.py',
                    'planets/saturn/moons/enceladus.py',
                    'planets/saturn/moons/iapetus.py',
                    'planets/saturn/moons/rhea.py',
                    'planets/saturn/moons/titan.py',
                ],
                'tests': [
                    'planets/hohmann_transfer_test.py',
                ]
            })

        update_config_with_packages(config=config,
                                    python_packages=[pkg1, pkg2])

        setup_cfg_text = io.StringIO()
        config.write(setup_cfg_text)
        expected_cfg = '''
[metadata]
name = megapackage
version = 0.0.1
author = Pigweed Authors
author_email = pigweed-developers@googlegroups.com
description = Pigweed swiss-army knife

[options]
zip_safe = False
packages = find:
install_requires =
    coloredlogs
    coverage
    cryptography
    graphlib-backport;python_version<'3.9'
    httpwatcher

[options.package_data]
megapackage =
    py.typed
mars =
    py.typed
saturn =
    py.typed

[options.entry_points]
'''
        result_cfg_lines = [
            line.rstrip().replace('\t', '    ')
            for line in setup_cfg_text.getvalue().splitlines() if line
        ]
        expected_cfg_lines = [
            line.rstrip() for line in expected_cfg.splitlines() if line
        ]
        self.assertEqual(expected_cfg_lines, result_cfg_lines)


    @parameterized.expand([
        (
            # Test name
            'working case',
            # Package name
            'mars',
            # File list
            [
                'planets/BUILD.mars_rocket',
                'planets/mars/__init__.py',
                'planets/mars/__main__.py',
                'planets/mars/moons/__init__.py',
                'planets/mars/moons/deimos.py',
                'planets/mars/moons/phobos.py',
                'planets/hohmann_transfer_test.py',
                'planets/pyproject.toml',
                'planets/setup.cfg',
            ],
            # Extra_files
            [],
            # Package definition
            {
                'generate_setup': {
                    'metadata': {
                        'name': 'mars',
                        'version': '0.0.1'
                    },
                },
                'inputs': [
                ],
                'setup_sources': [
                    'planets/pyproject.toml',
                    'planets/setup.cfg',
                ],
                'sources': [
                    'planets/mars/__init__.py',
                    'planets/mars/__main__.py',
                    'planets/mars/moons/__init__.py',
                    'planets/mars/moons/deimos.py',
                    'planets/mars/moons/phobos.py',
                ],
                'tests': [
                    'planets/hohmann_transfer_test.py',
                ],
            },
            # Output file list
            [
                'mars/__init__.py',
                'mars/__main__.py',
                'mars/moons/__init__.py',
                'mars/moons/deimos.py',
                'mars/moons/phobos.py',
                'mars/tests/hohmann_transfer_test.py',
            ],
        ),

        (
            # Test name
            'with extra files',
            # Package name
            'saturn',
            # File list
            [
                'planets/BUILD.saturn_rocket',
                'planets/hohmann_transfer_test.py',
                'planets/pyproject.toml',
                'planets/saturn/__init__.py',
                'planets/saturn/__main__.py',
                'planets/saturn/misson.py',
                'planets/saturn/moons/__init__.py',
                'planets/saturn/moons/enceladus.py',
                'planets/saturn/moons/iapetus.py',
                'planets/saturn/moons/rhea.py',
                'planets/saturn/moons/titan.py',
                'planets/setup.cfg',
                'planets/setup.py',
            ],
            # Extra files
            [
                'planets/BUILD.saturn_rocket > out/saturn/BUILD.rocket',
            ],
            # Package definition
            {
                'inputs': [
                ],
                'setup_sources': [
                    'planets/pyproject.toml',
                    'planets/setup.cfg',
                    'planets/setup.py',
                ],
                'sources': [
                    'planets/saturn/__init__.py',
                    'planets/saturn/__main__.py',
                    'planets/saturn/misson.py',
                    'planets/saturn/moons/__init__.py',
                    'planets/saturn/moons/enceladus.py',
                    'planets/saturn/moons/iapetus.py',
                    'planets/saturn/moons/rhea.py',
                    'planets/saturn/moons/titan.py',
                ],
                'tests': [
                    'planets/hohmann_transfer_test.py',
                ]
            },
            # Output file list
            [
                'saturn/BUILD.rocket',
                'saturn/__init__.py',
                'saturn/__main__.py',
                'saturn/misson.py',
                'saturn/moons/__init__.py',
                'saturn/moons/enceladus.py',
                'saturn/moons/iapetus.py',
                'saturn/moons/rhea.py',
                'saturn/moons/titan.py',
                'saturn/tests/hohmann_transfer_test.py',
            ],
        ),
    ]) # yapf: disable
    def test_build_python_tree(
        self,
        _test_name,
        package_name,
        file_list,
        extra_files,
        package_definition,
        expected_file_list,
    ) -> None:
        """Check results of build_python_tree and copy_extra_files."""
        temp_root = Path(self.temp_dir.name)
        _create_fake_python_package(temp_root, package_name, file_list)

        os.chdir(temp_root)
        install_dir = temp_root / 'out'

        package = PythonPackage.from_dict(**package_definition)
        build_python_tree(python_packages=[package],
                          tree_destination_dir=install_dir,
                          include_tests=True)
        copy_extra_files(extra_files)

        # Check expected files are in place.
        self._check_result_paths_equal(install_dir, expected_file_list)

    @parameterized.expand([
        (
            # Test name
            'everything in correct locations',
            # Package name
            'planets',
            # File list
            [
                'BUILD.mars_rocket',
            ],
            # Extra_files
            [
                'BUILD.mars_rocket > out/mars/BUILD.rocket',
            ],
            # Output file list
            [
                'mars/BUILD.rocket',
            ],
            # Should raise exception
            None,
        ),
        (
            # Test name
            'missing source files',
            # Package name
            'planets',
            # File list
            [
                'BUILD.mars_rocket',
            ],
            # Extra_files
            [
                'BUILD.venus_rocket > out/venus/BUILD.rocket',
            ],
            # Output file list
            [],
            # Should raise exception
            FileNotFoundError,
        ),
        (
            # Test name
            'existing destination files',
            # Package name
            'planets',
            # File list
            [
                'BUILD.jupiter_rocket',
                'out/jupiter/BUILD.rocket',
            ],
            # Extra_files
            [
                'BUILD.jupiter_rocket > out/jupiter/BUILD.rocket',
            ],
            # Output file list
            [],
            # Should raise exception
            FileExistsError,
        ),
    ]) # yapf: disable
    def test_copy_extra_files(
        self,
        _test_name,
        package_name,
        file_list,
        extra_files,
        expected_file_list,
        should_raise_exception,
    ) -> None:
        """Check results of build_python_tree and copy_extra_files."""
        temp_root = Path(self.temp_dir.name)
        _create_fake_python_package(temp_root, package_name, file_list)

        os.chdir(temp_root)
        install_dir = temp_root / 'out'

        # If exceptions should be raised
        if should_raise_exception:
            with self.assertRaises(should_raise_exception):
                copy_extra_files(extra_files)
            return

        # Do the copy
        copy_extra_files(extra_files)
        # Check expected files are in place.
        self._check_result_paths_equal(install_dir, expected_file_list)


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