"""Unit tests for SSH key preparation."""

import os
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest

from src.services.shared.ssh_keys import prepare_ssh_key_files


class TestPrepareSshKeyFiles:
    """Tests for prepare_ssh_key_files."""

    @patch("src.services.shared.ssh_keys._get_fernet")
    def test_creates_files_with_default_permissions(
        self, mock_fernet, tmp_path
    ) -> None:
        mock_fernet.return_value.decrypt.return_value = b"private-key-content"
        ssh_key = MagicMock()
        ssh_key.private_key_encrypted = "enc"
        ssh_key.public_key = "ssh-ed25519 AAA test@test"

        ssh_dir = prepare_ssh_key_files(str(tmp_path), ssh_key)

        assert Path(ssh_dir).exists()
        assert (Path(ssh_dir) / "id_ed25519").exists()
        assert (Path(ssh_dir) / "id_ed25519.pub").exists()
        assert (Path(ssh_dir) / "config").exists()
        assert oct(os.stat(Path(ssh_dir) / "id_ed25519").st_mode)[-3:] == "600"

    @patch("src.services.shared.ssh_keys._get_fernet")
    def test_sets_ownership_when_uid_gid_provided(self, mock_fernet, tmp_path) -> None:
        mock_fernet.return_value.decrypt.return_value = b"private-key-content"
        ssh_key = MagicMock()
        ssh_key.private_key_encrypted = "enc"
        ssh_key.public_key = "ssh-ed25519 AAA test@test"

        with patch("os.chown") as mock_chown:
            ssh_dir = prepare_ssh_key_files(str(tmp_path), ssh_key, uid=1001, gid=1001)

        # os.chown is called for the directory and each of the 3 files
        assert mock_chown.call_count == 4
        # First call is the directory
        assert mock_chown.call_args_list[0][0][1] == 1001
        assert mock_chown.call_args_list[0][0][2] == 1001

    @patch("src.services.shared.ssh_keys._get_fernet")
    def test_gracefully_handles_permission_error_on_chown(
        self, mock_fernet, tmp_path
    ) -> None:
        mock_fernet.return_value.decrypt.return_value = b"private-key-content"
        ssh_key = MagicMock()
        ssh_key.private_key_encrypted = "enc"
        ssh_key.public_key = "ssh-ed25519 AAA test@test"

        with patch("os.chown", side_effect=PermissionError("not allowed")):
            # Should not raise
            ssh_dir = prepare_ssh_key_files(str(tmp_path), ssh_key, uid=1001, gid=1001)

        assert Path(ssh_dir).exists()
