# Copyright (C) 2025  The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information

import hashlib

import pytest

from swh.model.swhids import CoreSWHID, ObjectType, QualifiedSWHID
from swh.storage.algos.swhid import known_swhids, swhid_is_known

from ..storage_data import StorageData


def test_known_swhids(swh_storage):
    swh_storage.snapshot_add([StorageData.snapshot])
    swh_storage.revision_add([StorageData.revision])
    swh_storage.release_add([StorageData.release])
    swh_storage.directory_add([StorageData.directory])
    swh_storage.content_add([StorageData.content])

    missing_snapshot_swhid = CoreSWHID.from_string(
        f"swh:1:snp:{hashlib.sha1(b'test snapshot').hexdigest()}"
    )
    missing_revision_swhid = CoreSWHID.from_string(
        f"swh:1:rev:{hashlib.sha1(b'test revision').hexdigest()}"
    )
    missing_release_swhid = CoreSWHID.from_string(
        f"swh:1:rel:{hashlib.sha1(b'test release').hexdigest()}"
    )
    missing_directory_swhid = CoreSWHID.from_string(
        f"swh:1:dir:{hashlib.sha1(b'test directory').hexdigest()}"
    )
    missing_content_swhid = CoreSWHID.from_string(
        f"swh:1:cnt:{hashlib.sha1(b'test content').hexdigest()}"
    )
    results = known_swhids(
        swh_storage,
        [
            StorageData.snapshot.swhid(),
            StorageData.revision.swhid(),
            StorageData.release.swhid(),
            StorageData.directory.swhid(),
            StorageData.content.swhid(),
            missing_snapshot_swhid,
            missing_revision_swhid,
            missing_release_swhid,
            missing_directory_swhid,
            missing_content_swhid,
        ],
    )

    assert len(results) == 5

    assert StorageData.snapshot.swhid() in results
    assert missing_snapshot_swhid not in results
    assert StorageData.revision.swhid() in results
    assert missing_revision_swhid not in results
    assert StorageData.release.swhid() in results
    assert missing_release_swhid not in results
    assert StorageData.directory.swhid() in results
    assert missing_directory_swhid not in results
    assert StorageData.content.swhid() in results
    assert missing_content_swhid not in results


def test_swhid_is_known(swh_storage):
    swh_storage.snapshot_add([StorageData.snapshot])
    missing_snapshot_swhid = CoreSWHID.from_string(
        f"swh:1:snp:{hashlib.sha1(b'test snapshot').hexdigest()}"
    )
    assert swhid_is_known(swh_storage, StorageData.snapshot.swhid())
    assert not swhid_is_known(swh_storage, missing_snapshot_swhid)


def test_does_not_handle_qualified_swhid(swh_storage):
    swhid = f"swh:1:snp:{hashlib.sha1(b'test qualified').hexdigest()}"
    qualified_swhid = QualifiedSWHID.from_string(swhid)
    with pytest.raises(TypeError) as exc:
        known_swhids(swh_storage, [qualified_swhid])
    assert swhid in str(exc.value)

    with pytest.raises(TypeError) as exc:
        swhid_is_known(swh_storage, qualified_swhid)
    assert swhid in str(exc.value)


def test_known_swhids_same_hash(swh_storage):
    swh_storage.content_add([StorageData.content])

    content_swhid = CoreSWHID(
        object_type=ObjectType.CONTENT, object_id=StorageData.content.sha1_git
    )

    directory_swhid = CoreSWHID(
        object_type=ObjectType.DIRECTORY, object_id=StorageData.content.sha1_git
    )

    assert known_swhids(swh_storage, [content_swhid, directory_swhid]) == {
        content_swhid
    }
