package healthcheck

import (
	"bufio"
	"fmt"
	"log/slog"
	"os"
	"path/filepath"
	"strings"
	"unicode"
)

// getNonAscii retrieves a list of files in the specified root directory that contain non-ASCII characters.
// It searches for non-ASCII characters in each file's content and returns a list of paths to files containing non-ASCII characters.
func getNonAscii(root string) ([]string, error) {
	var nonAscii []string

	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
			}
		}

		if info.Name() == "healthcheck" {
			return nil
		}

		file, err := os.Open(path)
		if err != nil {
			return err
		}
		defer file.Close()

		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			cont := true
			for _, c := range scanner.Text() {
				if c > unicode.MaxASCII {
					nonAscii = append(nonAscii, "\t"+path)
					cont = false
					break
				}
			}
			if !cont {
				break
			}
		}

		return nil
	})

	return nonAscii, err
}

// nonAsciiFiles checks for non-ASCII characters in files within the specified root directory.
// It prints a message with the paths to files containing non-ASCII characters, if any.
func NonAsciiFiles(root string) (jsonOut CheckStage) {
	jsonOut = CheckStage{
		Name:     "NonAsciiFiles",
		StdOut:   "Checking for non-ascii files: ",
		ExitCode: 0,
		StdErr:   "",
	}
	nonAscii, err := getNonAscii(root)
	if err != nil {
		jsonOut.StdOut += "Failed"
		jsonOut.ExitCode = 1
		slog.Error("get non-ascii", "err", err)
		return jsonOut
	}

	var nonAsciiRes string
	if len(nonAscii) > 0 {
		nonAsciiRes = fmt.Sprintf("Non-ASCII characters found in the following files:\n" + strings.Join(nonAscii, "\n"))
		jsonOut.ExitCode = 105
		jsonOut.StdOut += "Failed"
	} else {
		jsonOut.StdOut += "OK"
	}

	jsonOut.StdErr = nonAsciiRes

	return jsonOut
}