from pathlib import Path

import pytest
from black import FileMode, format_str

from jupytext.async_contentsmanager import __file__ as async_contentsmanager_file
from jupytext.async_pairs import __file__ as async_pairs_file
from jupytext.sync_contentsmanager import __file__ as sync_contentsmanager_file
from jupytext.sync_pairs import __file__ as sync_pairs_file


def generate_async_code_from_sync_code(async_code: str) -> str:
    # No async methods
    sync_code = async_code.replace("async def", "def")

    # Don't await
    sync_code = sync_code.replace("await ", "")

    # Rename the contents manager
    sync_code = sync_code.replace("AsyncLargeFileManager", "LargeFileManager")
    sync_code = sync_code.replace(
        "AsyncJupytextContentsManager", "SyncJupytextContentsManager"
    )
    sync_code = sync_code.replace(
        "AsyncTextFileContentsManager", "TextFileContentsManager"
    )
    sync_code = sync_code.replace("asynchronous", "synchronous")
    sync_code = sync_code.replace("async_", "sync_")

    # Add a header
    sync_code = f'''"""
This file is automatically generated by
tests/functional/contents_manager/test_async_and_sync_contents_manager_are_in_sync.py
Do not edit this file manually.
"""

{sync_code}'''
    sync_code = format_str(sync_code, mode=FileMode())

    return sync_code


@pytest.mark.parametrize(
    "async_file, sync_file",
    [
        (async_contentsmanager_file, sync_contentsmanager_file),
        (async_pairs_file, sync_pairs_file),
    ],
)
def test_async_and_sync_files_are_in_sync(async_file, sync_file):
    async_code = Path(async_file).read_text()
    sync_code = generate_async_code_from_sync_code(async_code)

    actual_sync_code = Path(sync_file).read_text()
    try:
        assert actual_sync_code == sync_code
    except AssertionError:
        Path(sync_file).write_text(sync_code)
        raise
