package main

import (
	"errors"
	"testing"

	"go.uber.org/mock/gomock"
	"src.opensuse.org/autogits/common"
	"src.opensuse.org/autogits/common/gitea-generated/models"
	mock_common "src.opensuse.org/autogits/common/mock"
)

func TestOpenPR(t *testing.T) {
	pr := PullRequestOpened{}

	config := &common.AutogitConfig{
		Reviewers:      []string{"reviewer1", "reviewer2"},
		Branch:         "branch",
		Organization:   "test",
		GitProjectName: "prj",
	}

	event := &common.PullRequestWebhookEvent{
		Action: "opened",
		Number: 1,
		Pull_Request: &common.PullRequest{
			Id: 1,
			Base: common.Head{
				Ref: "branch",
				Sha: "testing",
				Repo: &common.Repository{
					Name:           "testRepo",
					Default_Branch: "main1",
				},
			},
			Head: common.Head{
				Ref: "branch",
				Sha: "testing",
				Repo: &common.Repository{
					Name:           "testRepo",
					Default_Branch: "main1",
				},
			},
		},
		Repository: &common.Repository{
			Owner: &common.Organization{
				Username: "test",
			},
		},
	}

	git := &common.GitHandlerImpl{
		GitCommiter: "tester",
		GitEmail:    "test@suse.com",
	}

	t.Run("PR git opened request against PrjGit == no action", func(t *testing.T) {
		ctl := gomock.NewController(t)
		pr.gitea = mock_common.NewMockGitea(ctl)

		git.GitPath = t.TempDir()

		config.GitProjectName = "testRepo"
		event.Repository.Name = "testRepo"

		if err := pr.Process(event, git, config); err != nil {
			t.Error("Error PrjGit opened request. Should be no error.", err)
		}
	})

	t.Run("Open PrjGit PR", func(t *testing.T) {
		ctl := gomock.NewController(t)
		gitea := mock_common.NewMockGitea(ctl)

		pr.gitea = gitea

		event.Repository.Name = "testRepo"
		config.GitProjectName = "prjcopy"
		git.GitPath = t.TempDir()

		setupGitForTests(t, git)
		prjgit := &models.Repository{
			SSHURL:        "./prj",
			DefaultBranch: "testing",
		}
		giteaPR := &models.PullRequest{}
		gitea.EXPECT().CreateRepositoryIfNotExist(git, *event.Repository.Owner, "prjcopy").Return(prjgit, nil)
		gitea.EXPECT().CreatePullRequestIfNotExist(prjgit, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(giteaPR, nil)
		gitea.EXPECT().RequestReviews(giteaPR, "reviewer1").Return(nil, nil)
		gitea.EXPECT().RequestReviews(giteaPR, "reviewer2").Return(nil, nil)

		err := pr.Process(event, git, config)
		if err != nil {
			t.Error("error:", err)
		}
	})

	t.Run("Cannot create prjgit repository", func(t *testing.T) {
		ctl := gomock.NewController(t)
		gitea := mock_common.NewMockGitea(ctl)

		pr.gitea = gitea

		event.Repository.Name = "testRepo"
		config.GitProjectName = "prjcopy"
		git.GitPath = t.TempDir()

		setupGitForTests(t, git)
		failedErr := errors.New("Returned error here")
		gitea.EXPECT().CreateRepositoryIfNotExist(git, *event.Repository.Owner, "prjcopy").Return(nil, failedErr)

		err := pr.Process(event, git, config)
		if err != failedErr {
			t.Error("error:", err)
		}
	})
	t.Run("Cannot create PR", func(t *testing.T) {
		ctl := gomock.NewController(t)
		gitea := mock_common.NewMockGitea(ctl)

		pr.gitea = gitea

		event.Repository.Name = "testRepo"
		config.GitProjectName = "prjcopy"
		git.GitPath = t.TempDir()

		setupGitForTests(t, git)
		prjgit := &models.Repository{
			SSHURL:        "./prj",
			DefaultBranch: "testing",
		}
		failedErr := errors.New("Returned error here")
		gitea.EXPECT().CreateRepositoryIfNotExist(git, *event.Repository.Owner, "prjcopy").Return(prjgit, nil)
		gitea.EXPECT().CreatePullRequestIfNotExist(prjgit, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, failedErr)

		err := pr.Process(event, git, config)
		if err != failedErr {
			t.Error("error:", err)
		}
	})
	t.Run("Open PrjGit PR", func(t *testing.T) {
		ctl := gomock.NewController(t)
		gitea := mock_common.NewMockGitea(ctl)

		pr.gitea = gitea

		event.Repository.Name = "testRepo"
		config.GitProjectName = "prjcopy"
		git.GitPath = t.TempDir()

		setupGitForTests(t, git)
		prjgit := &models.Repository{
			Name:          "SomeRepo",
			Owner:         &models.User {
				UserName: "org",
			},
			SSHURL:        "./prj",
			DefaultBranch: "testing",
		}
		giteaPR := &models.PullRequest{
			Base: &models.PRBranchInfo {
				Repo: prjgit,
			},
			Index: 13,
		}
		failedErr := errors.New("Returned error here")
		gitea.EXPECT().CreateRepositoryIfNotExist(git, *event.Repository.Owner, "prjcopy").Return(prjgit, nil)
		gitea.EXPECT().CreatePullRequestIfNotExist(prjgit, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(giteaPR, nil)
		gitea.EXPECT().RequestReviews(giteaPR, "reviewer1").Return(nil, failedErr)
		// gitea.EXPECT().RequestReviews(giteaPR, "reviewer2").Return(nil, nil)

		err := pr.Process(event, git, config)
		if errors.Unwrap(err) != failedErr  {
			t.Error("error:", err)
		}
	})
}
