package connector

import (
	"encoding/json"
	"testing"

	"github.com/stretchr/testify/require"
)

// TestSHA256DigestMarshalJSON verifies that the digest is encoded
// as a lowercase hexadecimal JSON string.
func TestSHA256DigestMarshalJSON(t *testing.T) {
	t.Parallel()

	digest := NewSHA256Digest([]byte("hello world"))

	data, err := json.Marshal(digest)
	require.NoError(t, err)

	require.Equal(t, `"b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"`, string(data))
}

// TestSHA256DigestUnmarshalJSON verifies that a valid hexadecimal JSON string
// is decoded back into the original digest.
func TestSHA256DigestUnmarshalJSON(t *testing.T) {
	t.Parallel()

	var digest SHA256Digest
	err := json.Unmarshal(
		[]byte(`"b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"`),
		&digest,
	)
	require.NoError(t, err)

	expected := NewSHA256Digest([]byte("hello world"))
	require.True(t, digest.Equal(expected))
}

// TestSHA256DigestUnmarshalJSONInvalidLength verifies that invalid digest length
// is rejected.
func TestSHA256DigestUnmarshalJSONInvalidLength(t *testing.T) {
	t.Parallel()

	var digest SHA256Digest
	err := json.Unmarshal([]byte(`"abcd"`), &digest)

	require.Error(t, err)
	require.Contains(t, err.Error(), "invalid SHA-256 hex length")
}

// TestSHA256DigestUnmarshalJSONInvalidHex verifies that non-hexadecimal input
// is rejected.
func TestSHA256DigestUnmarshalJSONInvalidHex(t *testing.T) {
	t.Parallel()

	var digest SHA256Digest
	err := json.Unmarshal(
		[]byte(`"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"`),
		&digest,
	)

	require.Error(t, err)
	require.Contains(t, err.Error(), "invalid SHA-256 hex value")
}

// TestFileMetadataJSONRoundTrip verifies that a struct containing the digest
// round-trips correctly through JSON.
func TestFileMetadataJSONRoundTrip(t *testing.T) {
	t.Parallel()

	original := VersionInfo{
		OS:       "linux",
		Arch:     "amd64",
		Kind:     ArtifactKindExecutable,
		Version:  "1.2.3",
		URL:      "http://server:8080",
		Checksum: NewSHA256Digest([]byte("payload")),
	}

	data, err := json.Marshal(original)
	require.NoError(t, err)

	var decoded VersionInfo
	err = json.Unmarshal(data, &decoded)
	require.NoError(t, err)

	require.Equal(t, original.OS, decoded.OS)
	require.Equal(t, original.Arch, decoded.Arch)
	require.Equal(t, original.Kind, decoded.Kind)
	require.Equal(t, original.Version, decoded.Version)
	require.Equal(t, original.URL, decoded.URL)
	require.True(t, original.Checksum.Equal(decoded.Checksum))
}
