package jenkins

import (
	"net/url"
	"strings"
	"testing"

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

func TestJobPathEscapesEverySegment(t *testing.T) {
	path, err := jobPath([]string{"team", "release build"}, "/api/json", false)
	require.NoError(t, err)
	require.Equal(t, "/job/team/job/release%20build/api/json", path)

	root, err := jobPath(nil, "/api/json", true)
	require.NoError(t, err)
	require.Equal(t, "/api/json", root)
}

func TestJobPathRejectsInvalidSegments(t *testing.T) {
	testCases := []struct {
		name     string
		segments []string
	}{
		{name: "missing", segments: nil},
		{name: "empty", segments: []string{""}},
		{name: "dot", segments: []string{"."}},
		{name: "dot dot", segments: []string{".."}},
		{name: "slash", segments: []string{"team/release"}},
		{name: "backslash", segments: []string{`team\release`}},
		{name: "control", segments: []string{"release\n"}},
		{name: "too long", segments: []string{strings.Repeat("x", 257)}},
		{name: "too deep", segments: make([]string, 17)},
	}
	for index := range testCases[len(testCases)-1].segments {
		testCases[len(testCases)-1].segments[index] = "folder"
	}
	for _, testCase := range testCases {
		t.Run(testCase.name, func(t *testing.T) {
			_, err := jobPath(testCase.segments, "/api/json", false)
			require.Error(t, err)
		})
	}
}

func TestJobSegmentBudgetUsesUTF8Bytes(t *testing.T) {
	require.NoError(t, validateJobSegment(strings.Repeat("界", 85)))
	require.Error(t, validateJobSegment(strings.Repeat("界", 86)))
	require.Error(t, validateJobSegment("release\x00candidate"))
}

func TestParseQueueLocationAcceptsOnlySameTargetQueueItem(t *testing.T) {
	base, err := url.Parse("https://jenkins.example/jenkins")
	require.NoError(t, err)
	for _, location := range []string{
		"https://jenkins.example/jenkins/queue/item/42/",
		"https://JENKINS.example:443/jenkins/queue/item/42",
		"/jenkins/queue/item/42/",
	} {
		t.Run(location, func(t *testing.T) {
			queueID, err := parseQueueLocation(base, location)
			require.NoError(t, err)
			require.Equal(t, int64(42), queueID)
		})
	}
}

func TestParseQueueLocationRejectsMalformedOrEscapedValues(t *testing.T) {
	base, err := url.Parse("https://jenkins.example/jenkins")
	require.NoError(t, err)
	for _, location := range []string{
		"",
		"http://jenkins.example/jenkins/queue/item/42/",
		"https://other.example/jenkins/queue/item/42/",
		"https://user@jenkins.example/jenkins/queue/item/42/",
		"https://jenkins.example/queue/item/42/",
		"https://jenkins.example/jenkins/queue/item/0/",
		"https://jenkins.example/jenkins/queue/item/-1/",
		"https://jenkins.example/jenkins/queue/item/not-a-number/",
		"https://jenkins.example/jenkins/queue/item/9007199254740992/",
		"https://jenkins.example/jenkins/queue/item/9223372036854775808/",
		"https://jenkins.example/jenkins/queue/item/%34%32/",
		"https://jenkins.example/jenkins/queue/item/42/?secret=value",
		"https://jenkins.example/jenkins/queue/item/42/#fragment",
	} {
		t.Run(location, func(t *testing.T) {
			_, err := parseQueueLocation(base, location)
			require.Error(t, err)
			if location != "" {
				require.NotContains(t, err.Error(), location)
			}
		})
	}
}
