package perfdata // import nocternity.net/gomonop/pkg/perfdata

import (
	"fmt"
	"strings"
	"testing"

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

func TestRangeParserOk(t *testing.T) {
	type Test struct {
		in  string
		out Range
	}
	tests := []Test{
		{in: ":0", out: Range{start: "0", end: "0"}},
		{in: "0:0", out: Range{start: "0", end: "0"}},
		{in: "~:0", out: Range{start: "", end: "0"}},
		{in: ":123", out: Range{start: "0", end: "123"}},
		{in: "0:123", out: Range{start: "0", end: "123"}},
		{in: "~:123", out: Range{start: "", end: "123"}},
		{in: "1", out: Range{start: "0", end: "1"}},
		{in: "@:0", out: Range{start: "0", end: "0", inside: true}},
		{in: "@0:0", out: Range{start: "0", end: "0", inside: true}},
		{in: "@~:0", out: Range{start: "", end: "0", inside: true}},
		{in: "@:123", out: Range{start: "0", end: "123", inside: true}},
		{in: "@0:123", out: Range{start: "0", end: "123", inside: true}},
		{in: "@~:123", out: Range{start: "", end: "123", inside: true}},
		{in: "@1", out: Range{start: "0", end: "1", inside: true}},
	}

	for _, test := range tests {
		result, err := ParseRange(test.in)
		require.NoError(t, err, "Expected no error, got '%v'", err)
		assert.Equal(t, test.out, *result, "Expected '%v', got '%v'", test.out, *result)
	}
}

func TestRangeParserError(t *testing.T) {
	type Test struct {
		in     string
		errPos int
	}
	tests := []Test{
		{in: "", errPos: 0},
		{in: ":", errPos: 1},
		{in: "x:1", errPos: 0},
		{in: ":~", errPos: 1},
		{in: "@", errPos: 1},
		{in: "@:", errPos: 2},
		{in: "@x:1", errPos: 1},
		{in: "@:~", errPos: 2},
	}

	for _, test := range tests {
		result, err := ParseRange(test.in)
		require.Error(t, err, "Expected error, got '%v'", err)
		assert.Nil(t, result, "Expected nil result, got '%v'", result)
		assert.True(
			t, strings.Contains(err.Error(), fmt.Sprintf("at position %d", test.errPos)),
			"Expected error to contain '%s', got '%s'", fmt.Sprintf("at position %d", test.errPos), err,
		)
	}
}