package repo

import (
	"net/http"
	"strings"

	repo_model "code.gitea.io/gitea/models/repo"
	unit_model "code.gitea.io/gitea/models/unit"

	"code.gitea.io/gitea/modules/context"
	"code.gitea.io/gitea/modules/git"
	api "code.gitea.io/gitea/modules/structs"
	files_service "code.gitea.io/gitea/services/repository/files"
	hat_files_service "code.gitlink.org.cn/Gitlink/gitea_hat.git/services/repository/files"
)

func GetReadmeContents(ctx *context.APIContext) {
	if !canReadFiles(ctx.Repo) {
		ctx.Error(http.StatusInternalServerError, "canReadFiles", repo_model.ErrUserDoesNotHaveAccessToRepo{
			UserID:   ctx.ContextUser.ID,
			RepoName: ctx.Repo.Repository.LowerName,
		})
		return
	}

	ref := ctx.Params(":ref")
	readmePath := "README.md"
	readmezhPath := ""
	filesListInterface, err := files_service.GetContentsOrList(ctx, ctx.Repo.Repository, readmePath, ref)
	if err != nil {
		ctx.Error(http.StatusInternalServerError, "GetContentsOrList", err)
		return
	}
	filesList, ok := filesListInterface.([]*api.ContentsResponse)
	if ok {
		for _, file := range filesList {
			if strings.ToLower(file.Name) == "readme.md" {
				readmePath = file.Name
			}
			if strings.ToLower(file.Name) == "readme_zh.md" {
				readmezhPath = file.Name
			}
		}
	}

	if readmezhPath != "" {
		readmePath = readmezhPath
	}

	if fileList, err := files_service.GetContentsOrList(ctx, ctx.Repo.Repository, readmePath, ref); err != nil {
		if git.IsErrNotExist(err) {
			ctx.NotFound("GetContentsOrList", err)
			return
		}
		ctx.Error(http.StatusInternalServerError, "GetContentsOrList", err)

	} else {
		ctx.JSON(http.StatusOK, fileList)
	}
}

func canReadFiles(r *context.Repository) bool {
	return r.Permission.CanRead(unit_model.UnitCode.Type)
}

func GetReadmeContentsByPath(ctx *context.APIContext) {
	if !canReadFiles(ctx.Repo) {
		ctx.Error(http.StatusInternalServerError, "canReadFiles", repo_model.ErrUserDoesNotHaveAccessToRepo{
			UserID:   ctx.ContextUser.ID,
			RepoName: ctx.Repo.Repository.LowerName,
		})
		return
	}
	treePath := ctx.Params("*")
	ref := ctx.Params(":ref")
	readmePath := "README.md"
	readmezhPath := ""
	filesListInterface, err := files_service.GetContentsOrList(ctx, ctx.Repo.Repository, treePath, ref)
	if err != nil {
		ctx.Error(http.StatusInternalServerError, "GetContentsOrList", err)
		return
	}
	filesList, ok := filesListInterface.([]*api.ContentsResponse)
	if ok {
		for _, file := range filesList {
			if strings.ToLower(file.Name) == "readme.md" {
				readmePath = file.Name
			}
			if strings.ToLower(file.Name) == "readme_zh.md" {
				readmezhPath = file.Name
			}
		}
	}

	if readmezhPath != "" {
		readmePath = readmezhPath
	}

	newTreePath := treePath + "/" + readmePath
	if fileList, err := files_service.GetContentsOrList(ctx, ctx.Repo.Repository, newTreePath, ref); err != nil {
		if git.IsErrNotExist(err) {
			ctx.NotFound("GetContentsOrList", err)
			return
		}
		ctx.Error(http.StatusInternalServerError, "GetContentsOrList", err)

	} else {
		ctx.JSON(http.StatusOK, fileList)
	}
}

func GetContents(ctx *context.APIContext) {
	if !canReadFiles(ctx.Repo) {
		ctx.Error(http.StatusInternalServerError, "GetContents", repo_model.ErrUserDoesNotHaveAccessToRepo{
			UserID:   ctx.Doer.ID,
			RepoName: ctx.Repo.Repository.Name,
		})
		return
	}

	treePath := ctx.Params("*")
	ref := ctx.FormTrim("ref")

	if fileList, err := hat_files_service.GetContentsOrList(ctx, ctx.Repo.Repository, treePath, ref); err != nil {
		if git.IsErrNotExist(err) {
			ctx.NotFound("GetContentsOrList", err)
			return
		}
		ctx.Error(http.StatusInternalServerError, "GetContentsOrList", err)
	} else {
		ctx.JSON(http.StatusOK, fileList)
	}
}

func GetContentsList(ctx *context.APIContext) {
	GetContents(ctx)
}
