package gitaly

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/gitaly/vendored/gitalypb"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/tool/testing/matcher"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/tool/testing/mock_gitaly"
	"go.uber.org/mock/gomock"
)

const (
	revision1                  = "507ebc6de9bcac25628aa7afd52802a91a0685d8"
	agentConfigurationFilePath = ".gitlab/agents/any-agent/config.yaml"
)

var (
	_ PollerInterface = &Poller{}
)

func TestPoller_HappyPath(t *testing.T) {
	ctrl := gomock.NewController(t)
	r := repo()
	client := mock_gitaly.NewMockCommitServiceClient(ctrl)
	features := map[string]string{
		"f1": "true",
	}
	client.EXPECT().
		LastCommitForPath(matcher.GRPCOutgoingCtx(features), matcher.ProtoEq(nil, &gitalypb.LastCommitForPathRequest{
			Repository:      r,
			Revision:        []byte(DefaultBranch),
			Path:            []byte(agentConfigurationFilePath),
			LiteralPathspec: true,
		}), gomock.Any()).
		Return(&gitalypb.LastCommitForPathResponse{
			Commit: &gitalypb.GitCommit{
				Id: revision1,
			},
		}, nil)
	p := Poller{
		Client:   client,
		Features: features,
	}
	pollInfo, err := p.Poll(context.Background(), r, DefaultBranch, agentConfigurationFilePath)
	require.NoError(t, err)
	assert.Equal(t, revision1, pollInfo.CommitID)
}

func TestPoller_RefNotFound(t *testing.T) {
	ctrl := gomock.NewController(t)
	r := repo()
	client := mock_gitaly.NewMockCommitServiceClient(ctrl)
	client.EXPECT().
		LastCommitForPath(gomock.Any(), matcher.ProtoEq(nil, &gitalypb.LastCommitForPathRequest{
			Repository:      r,
			Revision:        []byte(DefaultBranch),
			Path:            []byte(agentConfigurationFilePath),
			LiteralPathspec: true,
		}), gomock.Any()).
		Return(&gitalypb.LastCommitForPathResponse{}, nil)
	p := Poller{
		Client: client,
	}
	pollInfo, err := p.Poll(context.Background(), r, DefaultBranch, agentConfigurationFilePath)
	require.NoError(t, err)
	assert.Empty(t, pollInfo.CommitID)
}

func repo() *gitalypb.Repository {
	return &gitalypb.Repository{
		StorageName:        "StorageName",
		RelativePath:       "RelativePath",
		GitObjectDirectory: "GitObjectDirectory",
		GlRepository:       "GlRepository",
		GlProjectPath:      "GlProjectPath",
	}
}
