import os
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch

from automio.wrapper import API, FilesApi


class TestWrapperFilesApi(unittest.TestCase):
    def test_api_exposes_files_api(self) -> None:
        with patch.dict(os.environ, {"APP_ID": "180"}, clear=False):
            api = API()
            self.assertIsInstance(api.files, FilesApi)

    def test_upload_uses_env_app_id(self) -> None:
        with patch.dict(os.environ, {"APP_ID": "180"}, clear=False):
            api = API()
            with patch.object(
                FilesApi,
                "apps_files_upload_create",
                return_value="uploaded",
            ) as mocked_upload:
                result = api.files.upload(
                    file=("report.txt", b"hello"),
                    path="exports/report.txt",
                    overwrite=True,
                )

        self.assertEqual(result, "uploaded")
        mocked_upload.assert_called_once_with(
            id=180,
            file=("report.txt", b"hello"),
            path="exports/report.txt",
            overwrite=True,
        )

    def test_upload_accepts_pathlike(self) -> None:
        with tempfile.NamedTemporaryFile(delete=False, suffix=".txt") as tmp_file:
            tmp_file.write(b"hello world")
            tmp_path = Path(tmp_file.name)

        try:
            with patch.dict(os.environ, {"APP_ID": "180"}, clear=False):
                api = API()
                with patch.object(
                    FilesApi,
                    "apps_files_upload_create",
                    return_value="uploaded",
                ) as mocked_upload:
                    api.files.upload(file=tmp_path, path="exports/report.txt")

            mocked_upload.assert_called_once()
            self.assertEqual(mocked_upload.call_args.kwargs["id"], 180)
            uploaded_file = mocked_upload.call_args.kwargs["file"]
            self.assertEqual(uploaded_file[0], tmp_path.name)
            self.assertEqual(uploaded_file[1], b"hello world")
        finally:
            tmp_path.unlink(missing_ok=True)

    def test_download_uses_env_app_id(self) -> None:
        with patch.dict(os.environ, {"APP_ID": "180"}, clear=False):
            api = API()
            with patch.object(
                FilesApi,
                "apps_files_download_retrieve",
                return_value="downloaded",
            ) as mocked_download:
                result = api.files.download("exports/report.txt")

        self.assertEqual(result, "downloaded")
        mocked_download.assert_called_once_with(id=180, path="exports/report.txt")

    def test_download_requires_integer_app_id(self) -> None:
        with patch.dict(os.environ, {"APP_ID": "org-slug/app-slug"}, clear=False):
            api = API()
            with self.assertRaisesRegex(ValueError, "app_id must be an integer"):
                api.files.download("exports/report.txt")


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