# Copyright 2022 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.
"""pw_ide test classes."""

from contextlib import contextmanager
from io import TextIOWrapper
from pathlib import Path
import tempfile
from typing import Generator, List, Optional, Tuple, Union
import unittest

from pw_ide.settings import IdeSettings


class TempDirTestCase(unittest.TestCase):
    """Run tests that need access to a temporary directory."""
    def setUp(self) -> None:
        self.temp_dir = tempfile.TemporaryDirectory()
        self.temp_dir_path = Path(self.temp_dir.name)

    def tearDown(self) -> None:
        self.temp_dir.cleanup()
        return super().tearDown()

    @contextmanager
    def make_temp_file(
        self,
        filename: Union[Path, str],
        content: str = ''
    ) -> Generator[Tuple[TextIOWrapper, Path], None, None]:
        """Create a temp file in the test case's temp dir.

        Returns a tuple containing the file reference and the file's path.
        The file can be read immediately.
        """
        path = self.temp_dir_path / filename

        with open(path, 'a+', encoding='utf-8') as file:
            file.write(content)
            file.flush()
            file.seek(0)
            yield (file, path)

    @contextmanager
    def make_temp_files(
        self, files_data: List[Tuple[Union[Path, str], str]]
    ) -> Generator[List[TextIOWrapper], None, None]:
        """Create several temp files in the test case's temp dir.

        Provide a list of file name and content tuples. Saves you the trouble
        of excessive `with self.make_temp_file, self.make_temp_file...`
        nesting, and allows programmatic definition of multiple temp file
        contexts. Files can be read immediately.
        """
        files: List[TextIOWrapper] = []

        for filename, content in files_data:
            file = open(self.path_in_temp_dir(filename),
                        'a+',
                        encoding='utf-8')
            file.write(content)
            file.flush()
            file.seek(0)
            files.append(file)

        yield files

        for file in files:
            file.close()

    def path_in_temp_dir(self, path: Union[Path, str]) -> Path:
        """Place a path into the test case's temp dir.

        This only works with a relative path; with an absolute path, this is a
        no-op.
        """
        return self.temp_dir_path / path

    def paths_in_temp_dir(self, *paths: Union[Path, str]) -> List[Path]:
        """Place several paths into the test case's temp dir.

        This only works with relative paths; with absolute paths, this is a
        no-op.
        """
        return [self.path_in_temp_dir(path) for path in paths]


class PwIdeTestCase(TempDirTestCase):
    """A test case for testing `pw_ide`.

    Provides a temp dir for testing file system actions and access to IDE
    settings that wrap the temp dir.
    """
    def make_ide_settings(self,
                          working_dir: Optional[Union[str, Path]] = None,
                          targets: Optional[List[str]] = None) -> IdeSettings:
        """Make settings that wrap provided paths in the temp path."""

        if working_dir is not None:
            working_dir_path = self.path_in_temp_dir(working_dir)
        else:
            working_dir_path = self.temp_dir_path

        if targets is None:
            targets = []

        return IdeSettings(False,
                           False,
                           False,
                           default_config={
                               'working_dir': str(working_dir_path),
                               'targets': targets,
                           })
