package continuous

import (
	"context"
	"net/url"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"
	"go.skia.org/infra/go/paramtools"
	"go.skia.org/infra/go/testutils"
	"go.skia.org/infra/perf/go/alerts"
	alertconfigmocks "go.skia.org/infra/perf/go/alerts/mock"
	"go.skia.org/infra/perf/go/clustering2"
	"go.skia.org/infra/perf/go/config"
	"go.skia.org/infra/perf/go/dataframe"
	"go.skia.org/infra/perf/go/dataframe/mocks"
	gitmocks "go.skia.org/infra/perf/go/git/mocks"
	"go.skia.org/infra/perf/go/git/provider"
	"go.skia.org/infra/perf/go/ingestevents"
	notifymocks "go.skia.org/infra/perf/go/notify/mocks"
	"go.skia.org/infra/perf/go/regression"
	regressionmocks "go.skia.org/infra/perf/go/regression/mocks"
	shortcutmocks "go.skia.org/infra/perf/go/shortcut/mocks"
	"go.skia.org/infra/perf/go/stepfit"
	"go.skia.org/infra/perf/go/types"
	"go.skia.org/infra/perf/go/ui/frame"
	"golang.org/x/exp/slices"
)

func TestBuildConfigsAndParamSet(t *testing.T) {
	mockConfigProvider := alertconfigmocks.NewConfigProvider(t)
	mockConfigProvider.On("GetAllAlertConfigs", testutils.AnyContext, false).Return(
		[]*alerts.Alert{
			{
				IDAsString: "1",
			},
			{
				IDAsString: "3",
			},
		}, nil)
	c := Continuous{
		provider: mockConfigProvider,
		paramsProvider: func() paramtools.ReadOnlyParamSet {
			return paramtools.ReadOnlyParamSet{
				"config": []string{"8888", "565"},
			}
		},
		pollingDelay: time.Nanosecond,
		instanceConfig: &config.InstanceConfig{
			DataStoreConfig: config.DataStoreConfig{},
			GitRepoConfig:   config.GitRepoConfig{},
			IngestionConfig: config.IngestionConfig{},
		},
		flags: &config.FrontendFlags{},
	}

	// Build channel.
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	ch := c.buildConfigAndParamsetChannel(ctx)

	// Read value.
	cnp := <-ch

	// Confirm it conforms to expectations.
	assert.Equal(t, c.paramsProvider(), cnp.paramset)
	assert.Len(t, cnp.configs, 2)
	ids := []string{}
	for _, cfg := range cnp.configs {
		ids = append(ids, cfg.IDAsString)
	}
	assert.Subset(t, []string{"1", "3"}, ids)

	// Confirm we continue to get items from the channel.
	cnp = <-ch
	assert.Equal(t, c.paramsProvider(), cnp.paramset)
}

func TestMatchingConfigsFromTraceIDs_TraceIDSliceIsEmpty_ReturnsEmptySlice(t *testing.T) {
	config := alerts.NewConfig()
	config.Query = "foo=bar"
	traceIDs := []string{}
	matchingConfigs := matchingConfigsFromTraceIDs(traceIDs, []*alerts.Alert{config})
	require.Empty(t, matchingConfigs)
}

func TestMatchingConfigsFromTraceIDs_OneConfigThatMatchesZeroTraces_ReturnsEmptySlice(t *testing.T) {
	config := alerts.NewConfig()
	config.Query = "arch=some-unknown-arch"
	traceIDs := []string{
		",arch=x86,config=8888,",
		",arch=arm,config=8888,",
	}
	matchingConfigs := matchingConfigsFromTraceIDs(traceIDs, []*alerts.Alert{config})
	require.Empty(t, matchingConfigs)
}

func TestMatchingConfigsFromTraceIDs_OneConfigThatMatchesOneTrace_ReturnsTheOneConfig(t *testing.T) {
	config := alerts.NewConfig()
	config.Query = "arch=x86"
	traceIDs := []string{
		",arch=x86,config=8888,",
		",arch=arm,config=8888,",
	}
	matchingConfigs := matchingConfigsFromTraceIDs(traceIDs, []*alerts.Alert{config})
	require.Len(t, matchingConfigs, 1)
}

func TestMatchingConfigsFromTraceIDs_TwoConfigsThatMatchesOneTrace_ReturnsBothConfigs(t *testing.T) {
	config1 := alerts.NewConfig()
	config1.Query = "arch=x86"
	config2 := alerts.NewConfig()
	config2.Query = "arch=arm"
	traceIDs := []string{
		",arch=x86,config=8888,",
		",arch=arm,config=8888,",
	}
	matchingConfigs := matchingConfigsFromTraceIDs(traceIDs, []*alerts.Alert{config1, config2})
	require.Len(t, matchingConfigs, 2)
}

func TestMatchingConfigsFromTraceIDs_GroupByMatchesTrace_ReturnsConfigWithRestrictedQuery(t *testing.T) {
	config1 := alerts.NewConfig()
	config1.Query = "arch=x86"
	config1.SetIDFromInt64(123)
	config1.GroupBy = "config"
	traceIDs := []string{
		",arch=x86,config=8888,",
		",arch=arm,config=8888,",
	}
	matchingConfigs := matchingConfigsFromTraceIDs(traceIDs, []*alerts.Alert{config1})
	require.Len(t, matchingConfigs, 1)

	for config, traces := range matchingConfigs {
		assert.Equal(t, config1.IDAsString, config.IDAsString)
		assert.Equal(t, config1.GroupBy, config.GroupBy)

		// Ensure that the query is updated inside the alert config
		assert.NotEqual(t, config1.Query, config.Query)
		assert.Equal(t, "arch=x86&config=8888", config.Query)

		assert.Equal(t, traceIDs[0], traces[0])
	}
}

func TestMatchingConfigsFromTraceIDs_MultipleGroupByPartsMatchTrace_ReturnsConfigWithRestrictedQueryUsingAllMatchingGroupByKeys(t *testing.T) {
	config := alerts.NewConfig()
	config.Query = "arch=x86"
	config.GroupBy = "config,device"
	traceIDs := []string{
		",arch=x86,config=8888,device=Pixel4,",
		",arch=arm,config=8888,device=Pixel4,",
	}
	matchingConfigs := matchingConfigsFromTraceIDs(traceIDs, []*alerts.Alert{config})
	require.Len(t, matchingConfigs, 1)
	for config := range matchingConfigs {
		assert.Equal(t, "arch=x86&config=8888&device=Pixel4", config.Query)
		_, err := url.ParseQuery(config.Query)
		require.NoError(t, err)
	}
}

type allMocks struct {
	perfGit          *gitmocks.Git
	shortcutStore    *shortcutmocks.Store
	regressionStore  *regressionmocks.Store
	notifier         *notifymocks.Notifier
	dataFrameBuilder *mocks.DataFrameBuilder
	configProvider   *alertconfigmocks.ConfigProvider
}

func createArgsForReportRegressions(t *testing.T) (*Continuous, *regression.RegressionDetectionRequest, []*regression.RegressionDetectionResponse, *alerts.Alert, allMocks) {
	pg := gitmocks.NewGit(t)
	ss := shortcutmocks.NewStore(t)
	rs := regressionmocks.NewStore(t)
	cp := alertconfigmocks.NewConfigProvider(t)
	n := notifymocks.NewNotifier(t)
	pp := func() paramtools.ReadOnlyParamSet {
		return nil
	}
	dfb := mocks.NewDataFrameBuilder(t)
	i := &config.InstanceConfig{}
	f := &config.FrontendFlags{}

	req := &regression.RegressionDetectionRequest{}
	resp := []*regression.RegressionDetectionResponse{}
	cfg := &alerts.Alert{}

	c := &Continuous{
		perfGit:        pg,
		shortcutStore:  ss,
		store:          rs,
		provider:       cp,
		notifier:       n,
		paramsProvider: pp,
		dfBuilder:      dfb,
		pollingDelay:   time.Microsecond,
		instanceConfig: i,
		flags:          f,
		current:        &alerts.Alert{},
	}

	allMocks := allMocks{
		perfGit:          pg,
		shortcutStore:    ss,
		regressionStore:  rs,
		notifier:         n,
		dataFrameBuilder: dfb,
		configProvider:   cp,
	}

	return c, req, resp, cfg, allMocks

}

func TestReportRegressions_EmptyRegressionDetectionResponse_NoRegressionsReported(t *testing.T) {
	c, req, resp, cfg, _ := createArgsForReportRegressions(t)
	// We know this works since we didn't need to supply any implementations for any of the mocks.
	c.reportRegressions(context.Background(), req, resp, cfg)
}

func TestReportRegressions_OneNewStepDownRegressionFound_OneRegressionStoredAndNotified(t *testing.T) {
	ctx := context.Background()
	c, req, resp, cfg, allMocks := createArgsForReportRegressions(t)

	const regressionCommitNumber = types.CommitNumber(2)
	resp = append(resp, &regression.RegressionDetectionResponse{
		Frame: &frame.FrameResponse{
			DataFrame: &dataframe.DataFrame{
				Header: []*dataframe.ColumnHeader{
					{Offset: 1},
					{Offset: regressionCommitNumber},
				},
				ParamSet: paramtools.ReadOnlyParamSet{
					"device_name": []string{"sailfish", "sargo", "wembley"},
				},
			},
		},
		Summary: &clustering2.ClusterSummaries{
			Clusters: []*clustering2.ClusterSummary{
				{
					Keys: []string{
						",device_name=sailfish",
						",device_name=sargo",
						",device_name=wembley",
					},
					Shortcut: "some-shortcut-id",
					StepFit: &stepfit.StepFit{
						Status: stepfit.LOW,
					},
					StepPoint: &dataframe.ColumnHeader{
						Offset: regressionCommitNumber,
					},
				},
			},
		},
	})

	commitAtStep := provider.Commit{
		Subject: "The subject of the commit where a regression occurred.",
	}
	previousCommit := provider.Commit{
		Subject: "The subject of the commit right before where a regression occurred.",
	}

	const notificationID = "some-notification-id"

	// First call to CommitFromCommitNumber.
	allMocks.perfGit.On("CommitFromCommitNumber", testutils.AnyContext, types.CommitNumber(2)).Return(commitAtStep, nil)

	// First call to CommitFromCommitNumber is for the previous commit.
	allMocks.perfGit.On("CommitFromCommitNumber", testutils.AnyContext, types.CommitNumber(1)).Return(previousCommit, nil)
	cfg.DirectionAsString = alerts.DOWN

	// Returns true to indicate that this is a newly found regression. Note that
	// this is called twice, first to store the regression since it's new, then
	// called again to store the notification ID.
	allMocks.regressionStore.On("SetLow", testutils.AnyContext, regressionCommitNumber, cfg.IDAsString, resp[0].Frame, resp[0].Summary.Clusters[0]).Return(true, "", nil).Twice()

	allMocks.notifier.On("RegressionFound", ctx, commitAtStep, previousCommit, cfg, resp[0].Summary.Clusters[0], resp[0].Frame, mock.Anything).Return(notificationID, nil)

	c.reportRegressions(ctx, req, resp, cfg)

	require.Equal(t, notificationID, resp[0].Summary.Clusters[0].NotificationID)
}

func TestTraceIdForIngestEvent_Matching(t *testing.T) {
	c, _, _, _, allMocks := createArgsForReportRegressions(t)

	allConfigs := []*alerts.Alert{
		{
			IDAsString: "1",
			Query:      "&id=trace1&id=trace3",
		},
		{
			IDAsString: "3",
			Query:      "&id=trace3",
		},
	}
	allMocks.configProvider.On("GetAllAlertConfigs", testutils.AnyContext, false).Return(
		allConfigs, nil)
	ctx := context.Background()
	ie := &ingestevents.IngestEvent{
		TraceIDs: []string{",id=trace1,", ",id=trace2,"},
	}
	configTracesMap, err := c.getTraceIdConfigsForIngestEvent(ctx, ie)
	assert.Nil(t, err)
	assert.NotNil(t, configTracesMap)
	for _, traces := range configTracesMap {
		assert.Equal(t, ie.TraceIDs[0], traces[0], "Expect the first config to match first trace.")
		assert.False(t, slices.Contains(traces, ie.TraceIDs[1]), "No match expected for second trace.")
	}

}

func TestTraceIdForIngestEvent_MultipleConfigs_Matching(t *testing.T) {
	c, _, _, _, allMocks := createArgsForReportRegressions(t)

	allConfigs := []*alerts.Alert{
		{
			IDAsString: "1",
			Query:      "&id=trace1&id=trace3",
		},
		{
			IDAsString: "3",
			Query:      "&id=trace3",
		},
	}
	allMocks.configProvider.On("GetAllAlertConfigs", testutils.AnyContext, false).Return(
		allConfigs, nil)
	ctx := context.Background()
	ie := &ingestevents.IngestEvent{
		TraceIDs: []string{",id=trace3,"},
	}
	configTracesMap, err := c.getTraceIdConfigsForIngestEvent(ctx, ie)
	assert.Nil(t, err)
	assert.NotNil(t, configTracesMap)
	assert.Equal(t, 2, len(configTracesMap))
}

func TestReportRegressions_OneNewStepDownRegressionFound_OneHighRegressionFoundAndNotified(t *testing.T) {
	ctx := context.Background()
	c, req, resp, cfg, allMocks := createArgsForReportRegressions(t)

	const regressionCommitNumber = types.CommitNumber(2)
	resp = append(resp, &regression.RegressionDetectionResponse{
		Frame: &frame.FrameResponse{
			DataFrame: &dataframe.DataFrame{
				Header: []*dataframe.ColumnHeader{
					{Offset: 1},
					{Offset: regressionCommitNumber},
				},
				ParamSet: paramtools.ReadOnlyParamSet{
					"device_name": []string{"sailfish", "sargo", "wembley"},
				},
			},
		},
		Summary: &clustering2.ClusterSummaries{
			Clusters: []*clustering2.ClusterSummary{
				{
					Keys: []string{
						",device_name=sailfish",
						",device_name=sargo",
						",device_name=wembley",
					},
					Shortcut: "some-shortcut-id",
					StepFit: &stepfit.StepFit{
						Status: stepfit.LOW,
					},
					StepPoint: &dataframe.ColumnHeader{
						Offset: regressionCommitNumber,
					},
				},
			},
		},
	}, &regression.RegressionDetectionResponse{
		Frame: &frame.FrameResponse{
			DataFrame: &dataframe.DataFrame{
				Header: []*dataframe.ColumnHeader{
					{Offset: 1},
					{Offset: regressionCommitNumber},
				},
				ParamSet: paramtools.ReadOnlyParamSet{
					"device_name": []string{"sailfish", "sargo", "wembley"},
				},
			},
		},
		Summary: &clustering2.ClusterSummaries{
			Clusters: []*clustering2.ClusterSummary{
				{
					Keys: []string{
						",device_name=sailfish",
						",device_name=sargo",
						",device_name=wembley",
					},
					Shortcut: "some-shortcut-id2",
					StepFit: &stepfit.StepFit{
						Status: stepfit.HIGH,
					},
					StepPoint: &dataframe.ColumnHeader{
						Offset: regressionCommitNumber,
					},
				},
			},
		},
	})

	commitAtStep := provider.Commit{
		Subject: "The subject of the commit where a regression occurred.",
	}
	previousCommit := provider.Commit{
		Subject: "The subject of the commit right before where a regression occurred.",
	}

	const notificationID = "some-notification-id"

	// First call to CommitFromCommitNumber.
	allMocks.perfGit.On("CommitFromCommitNumber", testutils.AnyContext, types.CommitNumber(2)).Return(commitAtStep, nil)

	// First call to CommitFromCommitNumber is for the previous commit.
	allMocks.perfGit.On("CommitFromCommitNumber", testutils.AnyContext, types.CommitNumber(1)).Return(previousCommit, nil)
	cfg.DirectionAsString = alerts.BOTH

	// Returns true to indicate that this is a newly found regression. Note that
	// this is called twice, first to store the regression since it's new, then
	// called again to store the notification ID.
	allMocks.regressionStore.On("SetLow", testutils.AnyContext, regressionCommitNumber, cfg.IDAsString, resp[0].Frame, resp[0].Summary.Clusters[0]).Return(true, "", nil).Twice()
	allMocks.regressionStore.On("SetHigh", testutils.AnyContext, regressionCommitNumber, cfg.IDAsString, resp[1].Frame, resp[1].Summary.Clusters[0]).Return(false, "", nil)
	allMocks.notifier.On("RegressionFound", ctx, commitAtStep, previousCommit, cfg, resp[0].Summary.Clusters[0], resp[0].Frame, mock.Anything).Return(notificationID, nil)

	allMocks.regressionStore.On("GetNotificationId", testutils.AnyContext, regressionCommitNumber, cfg.IDAsString).Return(notificationID, nil)
	allMocks.notifier.On("UpdateNotification", testutils.AnyContext, mock.Anything, mock.Anything, cfg, resp[1].Summary.Clusters[0], resp[1].Frame, notificationID).Return(nil)

	c.reportRegressions(ctx, req, resp, cfg)

	require.Equal(t, notificationID, resp[0].Summary.Clusters[0].NotificationID)
}
