package netmap

import (
	"strings"
	"testing"

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

var validPlacementPolicy = []string{
	`REP 2
CBF 2
SELECT 2 FROM *`,
	`REP 1 IN X
CBF 1
SELECT 2 IN SAME Location FROM * AS X`,

	`REP 1 IN X
REP 2 IN Y
CBF 1
SELECT 2 FROM * AS X
SELECT 3 FROM * AS Y`,

	`REP 1 IN X
SELECT 2 IN City FROM Good AS X
FILTER Country EQ RU AS FromRU
FILTER Country EQ EN AS FromEN
FILTER @FromRU AND @FromEN AND Rating GT 7 AS Good`,

	`REP 7 IN SPB
SELECT 1 IN City FROM SPBSSD AS SPB
FILTER City EQ SPB AND SSD EQ true OR City EQ SPB AND Rating GE 5 AS SPBSSD`,

	`REP 7 IN SPB
SELECT 1 IN City FROM SPBSSD AS SPB
FILTER NOT (NOT (City EQ SPB) AND SSD EQ true OR City EQ SPB AND Rating GE 5) AS SPBSSD`,

	`REP 1 IN FNODE
CBF 1
SELECT 1 FROM F AS FNODE
FILTER Node EQ '10.78.8.11' AS F`,

	`UNIQUE
REP 1
REP 1`,
	`EC 1.2 IN X
SELECT 3 IN City FROM * AS X`,
}

func TestDecodeString(t *testing.T) {
	var p PlacementPolicy

	for _, testCase := range validPlacementPolicy {
		require.NoError(t, p.DecodeString(testCase), "unable parse %s", testCase)
		var b strings.Builder
		require.NoError(t, p.WriteStringTo(&b))
		require.Equal(t, testCase, b.String())
	}

	invalidTestCases := map[string]error{
		`?REP 1`:                                errSyntaxError,
		`REP 1 trailing garbage`:                errSyntaxError,
		`REP 1 REP 1 SELECT 4 FROM *`:           errUnnamedSelector,
		`REP 1 SELECT 4 FROM * SELECT 1 FROM *`: errUnnamedSelector,
		`REP 1 IN X SELECT 4 FROM *`:            errUnknownSelector,
		`REP 1 IN X REP 2 SELECT 4 FROM * AS X FILTER 'UN-LOCODE' EQ 'RU LED' AS F`: errRedundantFilter,
	}

	for i := range invalidTestCases {
		require.ErrorIs(t, p.DecodeString(i), invalidTestCases[i], "#%s", i)
	}
}