package healthcheck

import (
	"fmt"
	"os"
	"path/filepath"
	"regexp"
)

// getForbiddens retrieves a list of forbidden files in the specified root directory.
// It searches for files that do not match the specified regex patterns in the given file list.
func getForbiddens(root string, fileList []string) ([]string, error) {
	var matches []string

	var regexList []*regexp.Regexp
	regexList, err := getRegex(fileList)
	if err != nil {
		fmt.Println("Error compiling regex:", err)
		return nil, err
	}

	err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if info.IsDir() {
			if info.Name() == ".git" || info.Name() == ".gitea" || info.Name() == "ci" {
				return filepath.SkipDir
			} else {
				return nil
			}
		}

		match := false
		for _, regex := range regexList {
			if regex.MatchString(info.Name()) {
				match = true
				break
			}
		}

		if !match {
			matches = append(matches, path)
		}
		return nil
	})

	return matches, err
}

// forbiddenCheck checks for forbidden files in the specified root directory.
// It prints the list of forbidden files found, along with instructions on how to fix them.
func ForbiddenCheck(rootDir string, regexList []string, repo string, droneBranch string) (jsonOut CheckStage) {
	jsonOut = CheckStage{
		Name:     "forbiddenFile",
		StdOut:   "Checking forbidden files: ",
		ExitCode: 0,
		StdErr:   "",
	}

	// INFO: test case
	// regexList := []string{`\.$`, `\.git`, `\.drone.yml`, `Makefile`, `CMakeLists.txt`,`.*\.go`,`.*\.toml`, `.*\.c`, `.*\.cc`, `.*\.cpp`, `.*\.h`, `.*\.md`}
	// rootDir = "/Users/zhouzhaojiacheng/Desktop/STUDENT_ORG/TechJI/Dev/joj/JOJ3"

	forbids, err := getForbiddens(rootDir, regexList)
	if err != nil {
		jsonOut.StdOut += "Failed"
		jsonOut.ExitCode = 1
		jsonOut.ErrorLog = err
		return jsonOut
	}

	var message string

	if len(forbids) > 0 {
		message += fmt.Sprint(103, "the following forbidden files were found: ")
		for _, file := range forbids {
			message += fmt.Sprint(file, ", ")
		}
		message += "\n\nTo fix it, first make a backup of your repository and then run the following commands:\nfor i in "
		for _, file := range forbids {
			message += fmt.Sprint(file, " ")
		}
		message += fmt.Sprint("; do git filter-repo --force --invert-paths --path \\\"\\$i\\\"; done\ngit remote add origin ", repo, "\ngit push --set-upstream origin ", droneBranch, " --force")
		jsonOut.StdOut += "Failed"
		jsonOut.ExitCode = 103
		jsonOut.StdErr = message
		return jsonOut
	} else {
		jsonOut.StdOut += "OK"
		return jsonOut
	}
}