from pathlib import Path

import pytest
from pydantic import AnyUrl
from pydantic.tools import parse_obj_as

from somesy.core.models import Person
from somesy.pyproject.writer import SetupTools


@pytest.fixture
def setuptools():
    return SetupTools(Path("tests/pyproject/data/pyproject.setuptools.toml"))


def test_init(tmp_path):
    file_path = tmp_path / "pyproject.toml"

    # check for error if file doesn't exist
    with pytest.raises(FileNotFoundError):
        SetupTools(file_path)


def test_key_error(setuptools):
    assert setuptools._get_property("not-existing") is None


def test_set_url(setuptools):
    # delete urls
    del setuptools._data["project"]["urls"]
    # set homepage
    setuptools.homepage = "https://test.test"
    assert setuptools.homepage == "https://test.test"


def test_name(setuptools):
    assert setuptools.name == "somesy"
    setuptools.name = "new name"
    assert setuptools.name == "new name"


def test_version(setuptools):
    assert setuptools.version == "0.0.1"
    setuptools.version = "0.0.2"
    assert setuptools.version == "0.0.2"


def test_description(setuptools):
    assert (
        setuptools.description
        == "A cli tool for synchronizing CITATION.CFF with project files."
    )
    setuptools.description = "new description"
    assert setuptools.description == "new description"


def test_authors(setuptools):
    # check existing authors
    authors = [
        Person(
            **{
                "email": "m.soylu@fz-juelich.de",
                "given-names": "Mustafa",
                "family-names": "Soylu",
            }
        )
    ]
    setuptools.authors = authors
    assert setuptools.authors == [
        {"name": "Mustafa Soylu", "email": "m.soylu@fz-juelich.de"}
    ]

    # set authors
    new_authors = [
        Person(**{"email": "aaa@aaa.aaa", "given-names": "AA", "family-names": "BB"}),
    ]
    setuptools.authors = new_authors
    assert setuptools.authors == [{"name": "AA BB", "email": "aaa@aaa.aaa"}]


def test_maintainers(setuptools):
    # check existing maintainers
    maintainers = [
        Person(
            **{
                "email": "m.soylu@fz-juelich.de",
                "given-names": "Mustafa",
                "family-names": "Soylu",
            }
        )
    ]
    setuptools.maintainers = maintainers
    assert setuptools.maintainers == [
        {"name": "Mustafa Soylu", "email": "m.soylu@fz-juelich.de"}
    ]

    # set maintainers
    new_maintainers = [
        Person(**{"email": "aaa@aaa.aaa", "given-names": "AA", "family-names": "BB"}),
    ]
    setuptools.maintainers = new_maintainers
    assert setuptools.maintainers == [{"name": "AA BB", "email": "aaa@aaa.aaa"}]


def test_license(setuptools):
    # check existing
    assert setuptools.license == "MIT"

    # set new
    setuptools.license = "GPT-3"
    assert setuptools.license == "GPT-3"


def test_keywords(setuptools):
    assert setuptools.keywords == ["metadata", "rdm", "FAIR", "framework"]
    setuptools.keywords = ["keyword1", "keyword2"]
    assert setuptools.keywords == ["keyword1", "keyword2"]


def test_homepage(setuptools):
    # as string
    assert (
        setuptools.homepage
        == "https://github.com/Materials-Data-Science-and-Informatics/somesy"
    )
    setuptools.homepage = "https://test.test"
    assert setuptools.homepage == "https://test.test"

    # as AnyUrl
    setuptools.homepage = parse_obj_as(AnyUrl, "https://test.test2")
    assert setuptools.homepage == "https://test.test2"


def test_repository(setuptools):
    # as string
    assert (
        setuptools.repository
        == "https://github.com/Materials-Data-Science-and-Informatics/somesy"
    )

    setuptools.repository = "https://test.test"
    assert setuptools.repository == "https://test.test"

    setuptools.repository = parse_obj_as(AnyUrl, "https://test.test2")
    assert setuptools.repository == "https://test.test2"


def test_save(tmp_path, create_setuptools_file):
    # test save with default path
    file_path = tmp_path / "pyproject.toml"
    create_setuptools_file(file_path)
    setuptools = SetupTools(file_path)
    setuptools.save()
    assert file_path.is_file()

    # test save with custom path
    custom_path = tmp_path / "custom.toml"
    setuptools.save(custom_path)
