package github

import (
	"fmt"

	"github.com/tidbcloud/devops/api"
	githubapi "github.com/tidbcloud/devops/api/github"
	gitent "github.com/tidbcloud/devops/entity/github"
	ctrl "github.com/tidbcloud/devops/pkg/controller"
	ghsvc "github.com/tidbcloud/devops/pkg/service/github"

	"github.com/gin-gonic/gin"
)

// ListRepositories
//
//	@Id				GithubControllerListRepositories
//	@Description	list repositories of an org
//	@Tags			GithubController
//	@Accept			json
//	@Produce		json
//	@Param			req	query		githubapi.ListRepositoriesReq	false	"request param"
//	@Success		200	{object}	githubapi.ListRepositoriesResp
//	@Router			/api/v1/devops/github/repos [get]
func (c *GithubController) ListRepositories(ctx *gin.Context) {
	req := &githubapi.ListRepositoriesReq{}
	err := ctx.ShouldBindQuery(req)
	if err != nil {
		ctrl.FailWithCode(ctx, err, api.ErrCodeInvalidArgument)
		return
	}

	param := ghsvc.ListRepositoryParam{
		Owners:       req.Owners,
		LocationLike: fmt.Sprintf("%%%s%%", req.LocationLike), // add % for like query
		Page:         int(req.Page),
		PerPage:      int(req.PerPage),
	}
	repos, total, err := c.svc.ListRepository(ctx, param)
	if err != nil {
		ctrl.Fail(ctx, err)
		return
	}

	resp := githubapi.ListRepositoriesResp{
		Total:        total,
		Repositories: repos,
	}

	ctrl.Success(ctx, resp)
}

// GetRepo
//
//	@Id				GithubControllerGetRepo
//	@Description	get a repo
//	@Tags			GithubController
//	@Accept			json
//	@Produce		json
//	@Param			owner	path		string	true	"owner name"
//	@Param			repo	path		string	true	"repo name"
//	@Success		200		{object}	githubapi.GetRepositoryResp
//	@Router			/api/v1/devops/github/repos/{owner}/{repo} [get]
func (c *GithubController) GetRepo(ctx *gin.Context) {
	owner := ctx.Param("owner")
	repo := ctx.Param("repo")
	if owner == "" || repo == "" {
		ctrl.FailWithCode(ctx, fmt.Errorf("owner and repo are required"), api.ErrCodeInvalidArgument)
		return
	}

	loc := gitent.NewRepoLocation(owner, repo)

	rp, err := c.svc.GetRepositoryByLoc(ctx, loc)
	if err != nil {
		ctrl.Fail(ctx, err)
		return
	}

	resp := githubapi.GetRepositoryResp{
		Repository: *rp,
	}
	ctrl.Success(ctx, resp)
}

// SyncRepositories
//
//	@Id				GithubControllerSyncRepositories
//	@Description	sync all repos manually
//	@Tags			GithubController
//	@Accept			json
//	@Produce		json
//	@Success		200	{object}	api.BaseResp
//	@Router			/api/v1/devops-internal/github/repos/sync [post]
func (c *GithubController) SyncRepositories(ctx *gin.Context) {
	err := c.svc.SyncRepository(ctx)
	if err != nil {
		ctrl.Fail(ctx, err)
		return
	}

	ctrl.Success(ctx, nil)
}
