package filterlist_test

import (
	"path/filepath"
	"testing"

	"github.com/AdguardTeam/golibs/testutil"
	"github.com/AdguardTeam/urlfilter/filterlist"
	"github.com/AdguardTeam/urlfilter/internal/uftest"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

// testFileRuleList is a path to the test file rule list.
var testFileRuleList = filepath.Join(testResourcesDir, "test_file_rule_list.txt")

func TestFile_RuleListScanner(t *testing.T) {
	t.Parallel()

	ruleList, err := filterlist.NewFile(&filterlist.FileConfig{
		Path: testFileRuleList,
		ID:   uftest.ListID1,
	})
	require.NoError(t, err)
	testutil.CleanupAndRequireSuccess(t, ruleList.Close)
	assert.Equal(t, uftest.ListID1, ruleList.ListID())

	scanner := ruleList.NewScanner()
	assert.True(t, scanner.Scan())

	f, idx := scanner.Rule()
	require.NotNil(t, f)

	assert.Equal(t, "||example.org", f.Text())
	assert.Equal(t, uftest.ListID1, f.GetFilterListID())
	assert.Equal(t, int64(0), idx)

	assert.True(t, scanner.Scan())

	f, idx = scanner.Rule()
	require.NotNil(t, f)

	assert.Equal(t, testRuleCosmetic, f.Text())
	assert.Equal(t, uftest.ListID1, f.GetFilterListID())
	assert.Equal(t, int64(21), idx)

	// Finish scanning.
	assert.False(t, scanner.Scan())

	f, err = ruleList.RetrieveRule(0)
	require.NoError(t, err)
	require.NotNil(t, f)

	assert.Equal(t, "||example.org", f.Text())
	assert.Equal(t, uftest.ListID1, f.GetFilterListID())

	f, err = ruleList.RetrieveRule(21)
	require.NoError(t, err)
	require.NotNil(t, f)

	assert.Equal(t, testRuleCosmetic, f.Text())
	assert.Equal(t, uftest.ListID1, f.GetFilterListID())
}

func BenchmarkFile_RetrieveRule(b *testing.B) {
	conf := &filterlist.FileConfig{
		Path: testFileRuleList,
		ID:   uftest.ListID1,
	}

	f, fileErr := filterlist.NewFile(conf)
	require.NoError(b, fileErr)
	testutil.CleanupAndRequireSuccess(b, f.Close)

	// Warmup to fill the buffer.
	r, err := f.RetrieveRule(0)
	require.NoError(b, err)

	b.ReportAllocs()
	for b.Loop() {
		r, err = f.RetrieveRule(0)
	}

	require.NoError(b, err)
	assert.NotNil(b, r)

	// Most recent results:
	//	goos: darwin
	//	goarch: arm64
	//	pkg: github.com/AdguardTeam/urlfilter/filterlist
	//	cpu: Apple M1 Pro
	//  BenchmarkFile_RetrieveRule-8   	  970134	      1218 ns/op	     448 B/op	       4 allocs/op
}
