__copyright__ = "Copyright (C) 2014-2019, 2021, 2024  Martin Blais"
__license__ = "GNU GPLv2"

import io
import os
import unittest
from os import path
from pathlib import Path

from beancount.utils import test_utils


class TestTestUtils(unittest.TestCase):
    def test_tempdir(self):
        with test_utils.tempdir() as tempdir:
            with open(path.join(tempdir, "file1"), "w", encoding="utf-8"):
                pass
            os.mkdir(path.join(tempdir, "directory"))
            with open(path.join(tempdir, "directory", "file2"), "w", encoding="utf-8"):
                pass
        self.assertFalse(path.exists(tempdir))
        self.assertFalse(path.exists(path.join(tempdir, "file1")))
        self.assertFalse(path.exists(path.join(tempdir, "directory")))

    def test_create_temporary_files(self):
        with test_utils.tempdir() as tmp:
            test_utils.create_temporary_files(
                tmp,
                {
                    "apples.beancount": """
                  include "{root}/fruits/oranges.beancount"

                  2014-01-01 open Assets:Apples
                """,
                    "fruits/oranges.beancount": """
                  2014-01-02 open Assets:Oranges
                """,
                },
            )

            # Check the total list of files.
            apples = Path(tmp, "apples.beancount")
            oranges = Path(tmp, "fruits/oranges.beancount")
            self.assertEqual(
                {apples, oranges},
                set(
                    Path(root, filename)
                    for root, _, files in os.walk(tmp)
                    for filename in files
                ),
            )

            # Check the contents of apples (with replacement of root).
            with open(apples, encoding="utf-8") as f:
                apples_content = f.read()
            self.assertRegex(apples_content, "open Assets:Apples")
            self.assertNotRegex(apples_content, "{root}")

            # Check the contents of oranges.
            with open(oranges, encoding="utf-8") as f:
                oranges_content = f.read()
            self.assertRegex(oranges_content, "open Assets:Oranges")

    def test_capture(self):
        text = "b9baaa0c-0f0a-47db-bffc-a00c6f4ac1db"
        with test_utils.capture() as output:
            self.assertTrue(isinstance(output, io.StringIO))
            print(text)
        self.assertEqual(text + "\n", output.getvalue())

    @test_utils.docfile
    def test_docfile(self, filename):
        "7f9034b1-51e7-420c-ac6b-945b5c594ebf"
        with open(filename, encoding="utf-8") as f:
            uuid = f.read()
        self.assertEqual("7f9034b1-51e7-420c-ac6b-945b5c594ebf", uuid)

    @test_utils.docfile_extra(suffix=".txt")
    def test_docfile_extra(self, filename):
        "7f9034b1-51e7-420c-ac6b-945b5c594ebf"
        with open(filename, encoding="utf-8") as f:
            uuid = f.read()
        self.assertEqual("7f9034b1-51e7-420c-ac6b-945b5c594ebf", uuid)
        self.assertTrue(".txt" in filename)

    def test_search_words(self):
        test_utils.search_words("i walrus is", "i am the walrus is not chicago")
        test_utils.search_words("i walrus is".split(), "i am the walrus is not chicago")

    def test_environ_contextmanager(self):
        with test_utils.environ("PATH", "/unlikely-to-be-your-path"):
            self.assertEqual("/unlikely-to-be-your-path", os.getenv("PATH"))
        self.assertNotEqual("/unlikely-to-be-your-path", os.getenv("PATH"))


class TestTestCase(test_utils.TestCase):
    def test_assertLines(self):
        self.assertLines(
            """
           43c62bff-8504-44ea-b5c0-afa218a7a973
           95ef1cc4-0016-4452-9f4e-1a053db2bc83
        """,
            """

             43c62bff-8504-44ea-b5c0-afa218a7a973
               95ef1cc4-0016-4452-9f4e-1a053db2bc83

        """,
        )

        with self.assertRaises(AssertionError):
            self.assertLines(
                """
               43c62bff-8504-44ea-b5c0-afa218a7a973
            """,
                """
                683f111f-f921-4db3-a3e8-daae344981e8
            """,
            )

    def test_assertOutput(self):
        with self.assertOutput("""
           3165efbc-c775-4503-be13-06b7167697a9
        """):
            print("3165efbc-c775-4503-be13-06b7167697a9")

        with self.assertRaises(AssertionError):
            with self.assertOutput("""
               3165efbc-c775-4503-be13-06b7167697a9
            """):
                print("78d58502a15e")


class TestSkipIfRaises(unittest.TestCase):
    def test_decorator(self):
        @test_utils.skipIfRaises(ValueError)
        def decorator_no_skip():
            pass

        decorator_no_skip()

        @test_utils.skipIfRaises(ValueError)
        def decorator_skip():
            raise ValueError

        with self.assertRaises(unittest.SkipTest):
            decorator_skip()

    def test_decorator_many(self):
        @test_utils.skipIfRaises(ValueError, IndexError)
        def decorator_skip():
            raise ValueError

        with self.assertRaises(unittest.SkipTest):
            decorator_skip()

    def test_contextmanager(self):
        with test_utils.skipIfRaises(ValueError):
            pass

        with self.assertRaises(unittest.SkipTest):
            with test_utils.skipIfRaises(ValueError):
                raise ValueError


@test_utils.nottest
def test_not_really():
    assert False


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