"""Tests for all PBX/XC object types."""

from xproject_creator.objects import (
    PBXAggregateTarget,
    PBXBuildFile,
    PBXContainerItemProxy,
    PBXCopyFilesBuildPhase,
    PBXFileReference,
    PBXFileSystemSynchronizedRootGroup,
    PBXFrameworksBuildPhase,
    PBXGroup,
    PBXNativeTarget,
    PBXObject,
    PBXProject,
    PBXResourcesBuildPhase,
    PBXShellScriptBuildPhase,
    PBXSourcesBuildPhase,
    PBXTargetDependency,
    XCBuildConfiguration,
    XCConfigurationList,
)


def test_pbxobject_base():
    obj = PBXObject("AAAAAAAAAAAAAAAAAAAAAAAA")
    assert obj.object_key == "AAAAAAAAAAAAAAAAAAAAAAAA"
    assert obj.comment is None
    assert obj.to_dict() == {"isa": "PBXObject"}


def test_pbxbuildfile_basic():
    bf = PBXBuildFile("A" * 24, file_ref="B" * 24)
    assert bf.isa == "PBXBuildFile"
    assert bf.comment is None  # no file_ref_comment
    d = bf.to_dict()
    assert d["fileRef"] == "B" * 24
    assert "settings" not in d


def test_pbxbuildfile_with_settings():
    bf = PBXBuildFile(
        "A" * 24,
        file_ref="B" * 24,
        file_ref_comment="MyFile.swift",
        settings={"ATTRIBUTES": ["RemoveHeadersOnCopy"]},
    )
    assert bf.comment == "MyFile.swift in Sources"
    d = bf.to_dict()
    assert d["settings"] == {"ATTRIBUTES": ["RemoveHeadersOnCopy"]}


def test_pbxfilereference_minimal():
    fr = PBXFileReference("A" * 24, "test.swift", last_known_file_type="sourcecode.swift")
    assert fr.comment == "test.swift"
    d = fr.to_dict()
    assert d["path"] == "test.swift"
    assert d["sourceTree"] == "<group>"
    assert d["lastKnownFileType"] == "sourcecode.swift"
    assert "explicitFileType" not in d
    assert "name" not in d
    assert "includeInIndex" not in d


def test_pbxfilereference_product():
    fr = PBXFileReference(
        "A" * 24,
        "MyApp.app",
        source_tree="BUILT_PRODUCTS_DIR",
        explicit_file_type="wrapper.application",
        include_in_index="0",
    )
    assert fr.comment == "MyApp.app"
    d = fr.to_dict()
    assert d["explicitFileType"] == "wrapper.application"
    assert d["includeInIndex"] == "0"
    assert d["sourceTree"] == "BUILT_PRODUCTS_DIR"


def test_pbxfilereference_with_name():
    fr = PBXFileReference("A" * 24, "Base.lproj/Main.storyboard", name="Base")
    assert fr.comment == "Base"
    d = fr.to_dict()
    assert d["name"] == "Base"


def test_pbxgroup_basic():
    g = PBXGroup("A" * 24, children=["B" * 24], path="src")
    assert g.comment == "src"
    d = g.to_dict()
    assert d["children"] == ["B" * 24]
    assert d["path"] == "src"
    assert d["sourceTree"] == "<group>"
    assert "name" not in d


def test_pbxgroup_with_name():
    g = PBXGroup("A" * 24, name="Products")
    assert g.comment == "Products"
    d = g.to_dict()
    assert d["name"] == "Products"
    assert "path" not in d


def test_pbxgroup_empty():
    g = PBXGroup("A" * 24)
    assert g.children == []
    assert g.comment is None


def test_pbxsourcesbuildphase():
    sp = PBXSourcesBuildPhase("A" * 24, files=["B" * 24])
    assert sp.comment == "Sources"
    d = sp.to_dict()
    assert d["files"] == ["B" * 24]
    assert d["buildActionMask"] == "2147483647"
    assert d["runOnlyForDeploymentPostprocessing"] == "0"


def test_pbxresourcesbuildphase():
    rp = PBXResourcesBuildPhase("A" * 24)
    assert rp.comment == "Resources"
    assert rp.files == []


def test_pbxframeworksbuildphase():
    fp = PBXFrameworksBuildPhase("A" * 24)
    assert fp.comment == "Frameworks"
    d = fp.to_dict()
    assert d["isa"] == "PBXFrameworksBuildPhase"


def test_pbxcopyfilesbuildphase_default():
    cp = PBXCopyFilesBuildPhase("A" * 24)
    assert cp.comment == "CopyFiles"
    d = cp.to_dict()
    assert d["dstPath"] == ""
    assert d["dstSubfolderSpec"] == "16"
    assert "name" not in d


def test_pbxcopyfilesbuildphase_named():
    cp = PBXCopyFilesBuildPhase(
        "A" * 24,
        name="Embed Frameworks",
        dst_subfolder_spec=10,
        files=["B" * 24],
    )
    assert cp.comment == "Embed Frameworks"
    d = cp.to_dict()
    assert d["name"] == "Embed Frameworks"
    assert d["dstSubfolderSpec"] == "10"
    assert d["files"] == ["B" * 24]


def test_pbxshellscriptbuildphase():
    sp = PBXShellScriptBuildPhase(
        "A" * 24,
        name="Lint",
        shell_script="swiftlint",
        input_paths=["/src"],
        output_paths=["/out"],
    )
    assert sp.comment == "Lint"
    d = sp.to_dict()
    assert d["name"] == "Lint"
    assert d["shellPath"] == "/bin/sh"
    assert d["shellScript"] == "swiftlint"
    assert d["inputPaths"] == ["/src"]
    assert d["outputPaths"] == ["/out"]
    assert d["files"] == []


def test_pbxnativetarget():
    nt = PBXNativeTarget(
        "A" * 24,
        name="MyApp",
        product_name="MyApp",
        product_type="com.apple.product-type.application",
        product_reference="B" * 24,
        build_configuration_list="C" * 24,
        build_phases=["D" * 24],
        build_rules=["E" * 24],
        dependencies=["F" * 24],
    )
    assert nt.comment == "MyApp"
    d = nt.to_dict()
    assert d["name"] == "MyApp"
    assert d["productName"] == "MyApp"
    assert d["productType"] == "com.apple.product-type.application"
    assert d["productReference"] == "B" * 24
    assert d["buildConfigurationList"] == "C" * 24
    assert d["buildPhases"] == ["D" * 24]
    assert d["buildRules"] == ["E" * 24]
    assert d["dependencies"] == ["F" * 24]
    assert "packageProductDependencies" not in d


def test_pbxnativetarget_with_packages():
    nt = PBXNativeTarget(
        "A" * 24,
        name="MyApp",
        product_name="MyApp",
        product_type="com.apple.product-type.application",
        product_reference="B" * 24,
        build_configuration_list="C" * 24,
        package_product_dependencies=["G" * 24],
    )
    d = nt.to_dict()
    assert d["packageProductDependencies"] == ["G" * 24]


def test_pbxaggregatetarget():
    at = PBXAggregateTarget(
        "A" * 24,
        name="Aggregate",
        build_configuration_list="C" * 24,
        build_phases=["D" * 24],
        dependencies=["F" * 24],
    )
    assert at.comment == "Aggregate"
    d = at.to_dict()
    assert d["isa"] == "PBXAggregateTarget"
    assert d["name"] == "Aggregate"
    assert d["buildPhases"] == ["D" * 24]
    assert d["dependencies"] == ["F" * 24]


def test_pbxproject():
    proj = PBXProject(
        "A" * 24,
        build_configuration_list="B" * 24,
        main_group="C" * 24,
        targets=["D" * 24],
        product_ref_group="E" * 24,
    )
    assert proj.comment == "Project object"
    d = proj.to_dict()
    assert d["isa"] == "PBXProject"
    assert d["buildConfigurationList"] == "B" * 24
    assert d["mainGroup"] == "C" * 24
    assert d["targets"] == ["D" * 24]
    assert d["productRefGroup"] == "E" * 24
    assert d["hasScannedForEncodings"] == "0"
    assert d["knownRegions"] == ["en", "Base"]
    assert d["compatibilityVersion"] == "Xcode 14.0"


def test_pbxproject_no_product_ref_group():
    proj = PBXProject(
        "A" * 24,
        build_configuration_list="B" * 24,
        main_group="C" * 24,
    )
    d = proj.to_dict()
    assert "productRefGroup" not in d
    assert d["targets"] == []


def test_pbxtargetdependency():
    td = PBXTargetDependency(
        "A" * 24,
        target="B" * 24,
        target_proxy="C" * 24,
    )
    assert td.comment == "PBXTargetDependency"
    d = td.to_dict()
    assert d["target"] == "B" * 24
    assert d["targetProxy"] == "C" * 24


def test_pbxcontaineritemproxy():
    cip = PBXContainerItemProxy(
        "A" * 24,
        container_portal="B" * 24,
        remote_global_id_string="C" * 24,
        remote_info="MyTarget",
    )
    assert cip.comment == "PBXContainerItemProxy"
    d = cip.to_dict()
    assert d["containerPortal"] == "B" * 24
    assert d["proxyType"] == "1"
    assert d["remoteGlobalIDString"] == "C" * 24
    assert d["remoteInfo"] == "MyTarget"


def test_xcbuildconfiguration():
    cfg = XCBuildConfiguration(
        "A" * 24,
        name="Debug",
        build_settings={"SWIFT_VERSION": "5.0", "SDKROOT": "iphoneos"},
    )
    assert cfg.comment == "Debug"
    d = cfg.to_dict()
    assert d["name"] == "Debug"
    assert d["buildSettings"]["SWIFT_VERSION"] == "5.0"


def test_xcbuildconfiguration_empty_settings():
    cfg = XCBuildConfiguration("A" * 24, name="Release")
    d = cfg.to_dict()
    assert d["buildSettings"] == {}


def test_xcconfigurationlist():
    cl = XCConfigurationList(
        "A" * 24,
        build_configurations=["B" * 24, "C" * 24],
        comment_name="MyApp",
    )
    assert cl.comment == 'Build configuration list for PBXNativeTarget "MyApp"'
    d = cl.to_dict()
    assert d["buildConfigurations"] == ["B" * 24, "C" * 24]
    assert d["defaultConfigurationName"] == "Release"
    assert d["defaultConfigurationIsVisible"] == "0"


def test_xcconfigurationlist_project():
    cl = XCConfigurationList(
        "A" * 24,
        build_configurations=["B" * 24],
    )
    assert cl.comment == "Build configuration list for PBXProject"


def test_pbxfilesystemsynchronizedrootgroup_basic():
    g = PBXFileSystemSynchronizedRootGroup("A" * 24, path="MyApp")
    assert g.isa == "PBXFileSystemSynchronizedRootGroup"
    assert g.comment == "MyApp"
    d = g.to_dict()
    assert d["isa"] == "PBXFileSystemSynchronizedRootGroup"
    assert d["path"] == "MyApp"
    assert d["sourceTree"] == "<group>"
    assert "exceptions" not in d


def test_pbxfilesystemsynchronizedrootgroup_with_exceptions():
    g = PBXFileSystemSynchronizedRootGroup("A" * 24, path="MyApp", exceptions=["B" * 24])
    d = g.to_dict()
    assert d["exceptions"] == ["B" * 24]


def test_pbxnativetarget_with_file_sync_groups():
    nt = PBXNativeTarget(
        "A" * 24,
        name="MyApp",
        product_name="MyApp",
        product_type="com.apple.product-type.application",
        product_reference="B" * 24,
        build_configuration_list="C" * 24,
        file_system_synchronized_groups=["D" * 24],
    )
    d = nt.to_dict()
    assert d["fileSystemSynchronizedGroups"] == ["D" * 24]


def test_pbxnativetarget_no_file_sync_groups():
    nt = PBXNativeTarget(
        "A" * 24,
        name="MyApp",
        product_name="MyApp",
        product_type="com.apple.product-type.application",
        product_reference="B" * 24,
        build_configuration_list="C" * 24,
    )
    d = nt.to_dict()
    assert "fileSystemSynchronizedGroups" not in d


def test_pbxproject_v77():
    proj = PBXProject(
        "A" * 24,
        build_configuration_list="B" * 24,
        main_group="C" * 24,
        compatibility_version=None,
        minimized_project_reference_proxies="1",
        preferred_project_object_version="77",
    )
    d = proj.to_dict()
    assert "compatibilityVersion" not in d
    assert d["minimizedProjectReferenceProxies"] == "1"
    assert d["preferredProjectObjectVersion"] == "77"


def test_pbxproject_classic_has_compatibility_version():
    proj = PBXProject(
        "A" * 24,
        build_configuration_list="B" * 24,
        main_group="C" * 24,
    )
    d = proj.to_dict()
    assert d["compatibilityVersion"] == "Xcode 14.0"
    assert "minimizedProjectReferenceProxies" not in d
    assert "preferredProjectObjectVersion" not in d
