// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package integration

import (
	"fmt"
	"net/http"
	"net/url"
	"testing"

	auth_model "gitea.dev/models/auth"
	repo_model "gitea.dev/models/repo"
	"gitea.dev/models/unittest"
	user_model "gitea.dev/models/user"

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

func TestActionsCollaborativeOwner(t *testing.T) {
	onGiteaRun(t, func(t *testing.T, u *url.URL) {
		// user2 is the owner of the private "reusable_workflow" repo
		user2Session := loginUser(t, "user2")
		user2Token := getTokenForLoggedInUser(t, user2Session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
		apiReusableWorkflowRepo := createActionsTestRepo(t, user2Token, "reusable_workflow", true)
		reusableWorkflowRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiReusableWorkflowRepo.ID})

		// user4 is the owner of the private caller repo
		user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
		user4Session := loginUser(t, user4.Name)
		user4Token := getTokenForLoggedInUser(t, user4Session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
		apiCallerRepo := createActionsTestRepo(t, user4Token, "caller_workflow", true)
		callerRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiCallerRepo.ID})

		// create a mock runner for caller
		runner := newMockRunner()
		runner.registerAsRepoRunner(t, callerRepo.OwnerName, callerRepo.Name, "mock-runner", []string{"ubuntu-latest"}, false)

		// init the workflow for caller
		wfTreePath := ".gitea/workflows/test_collaborative_owner.yml"
		wfFileContent := `name: Test Collaborative Owner
on: push
jobs:
  job1:
    runs-on: ubuntu-latest
    steps:
      - run: echo 'test collaborative owner'
`
		opts := getWorkflowCreateFileOptions(user4, callerRepo.DefaultBranch, "create "+wfTreePath, wfFileContent)
		createWorkflowFile(t, user4Token, callerRepo.OwnerName, callerRepo.Name, wfTreePath, opts)

		// fetch the task and get its token
		task := runner.fetchTask(t)
		taskToken := task.Secrets["GITEA_TOKEN"]
		assert.NotEmpty(t, taskToken)

		// prepare for clone
		dstPath := t.TempDir()
		u.Path = fmt.Sprintf("%s/%s.git", "user2", "reusable_workflow")
		u.User = url.UserPassword("gitea-actions", taskToken)

		// the git clone will fail
		doGitCloneFail(u)(t)

		// add user10 to the list of collaborative owners
		req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/settings/actions/general/collaborative_owner/add", reusableWorkflowRepo.OwnerName, reusableWorkflowRepo.Name), map[string]string{
			"collaborative_owner": user4.Name,
		})
		user2Session.MakeRequest(t, req, http.StatusOK)

		// the git clone will be successful
		doGitClone(dstPath, u)(t)

		// remove user10 from the list of collaborative owners
		req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/settings/actions/general/collaborative_owner/delete?id=%d", reusableWorkflowRepo.OwnerName, reusableWorkflowRepo.Name, user4.ID))
		user2Session.MakeRequest(t, req, http.StatusOK)

		// the git clone will fail
		doGitCloneFail(u)(t)
	})
}
