package bashkit

import (
	"fmt"
	"strings"

	"mvdan.cc/sh/v3/syntax"
)

var checks = []func(*syntax.CallExpr) error{
	noGitConfigUsernameEmailChanges,
	noBlindGitAdd,
}

// Check inspects bashScript and returns an error if it ought not be executed.
// Check DOES NOT PROVIDE SECURITY against malicious actors.
// It is intended to catch straightforward mistakes in which a model
// does things despite having been instructed not to do them.
func Check(bashScript string) error {
	r := strings.NewReader(bashScript)
	parser := syntax.NewParser()
	file, err := parser.Parse(r, "")
	if err != nil {
		// Execution will fail, but we'll get a better error message from bash.
		// Note that if this were security load bearing, this would be a terrible idea:
		// You could smuggle stuff past Check by exploiting differences in what is considered syntactically valid.
		// But it is not.
		return nil
	}

	syntax.Walk(file, func(node syntax.Node) bool {
		if err != nil {
			return false
		}
		callExpr, ok := node.(*syntax.CallExpr)
		if !ok {
			return true
		}
		for _, check := range checks {
			err = check(callExpr)
			if err != nil {
				return false
			}
		}
		return true
	})

	return err
}

// noGitConfigUsernameEmailChanges checks for git config username/email changes.
// It uses simple heuristics, and has both false positives and false negatives.
func noGitConfigUsernameEmailChanges(cmd *syntax.CallExpr) error {
	if hasGitConfigUsernameEmailChanges(cmd) {
		return fmt.Errorf("permission denied: changing git config username/email is not allowed, use env vars instead")
	}
	return nil
}

func hasGitConfigUsernameEmailChanges(cmd *syntax.CallExpr) bool {
	if len(cmd.Args) < 3 {
		return false
	}
	if cmd.Args[0].Lit() != "git" {
		return false
	}

	configIndex := -1
	for i, arg := range cmd.Args {
		if arg.Lit() == "config" {
			configIndex = i
			break
		}
	}

	if configIndex < 0 || configIndex == len(cmd.Args)-1 {
		return false
	}

	// check for user.name or user.email
	keyIndex := -1
	for i, arg := range cmd.Args {
		if i < configIndex {
			continue
		}
		if arg.Lit() == "user.name" || arg.Lit() == "user.email" {
			keyIndex = i
			break
		}
	}

	if keyIndex < 0 || keyIndex == len(cmd.Args)-1 {
		return false
	}

	// user.name/user.email is followed by a value
	return true
}

// WillRunGitCommit checks if the provided bash script will run 'git commit'.
// It returns true if any command in the script is a git commit command.
func WillRunGitCommit(bashScript string) (bool, error) {
	r := strings.NewReader(bashScript)
	parser := syntax.NewParser()
	file, err := parser.Parse(r, "")
	if err != nil {
		// Parsing failed, but let's not consider this an error for the same reasons as in Check
		return false, nil
	}

	willCommit := false

	syntax.Walk(file, func(node syntax.Node) bool {
		callExpr, ok := node.(*syntax.CallExpr)
		if !ok {
			return true
		}
		if isGitCommitCommand(callExpr) {
			willCommit = true
			return false
		}
		return true
	})

	return willCommit, nil
}

// noBlindGitAdd checks for git add commands that blindly add all files.
// It rejects patterns like 'git add -A', 'git add .', 'git add --all', 'git add *'.
func noBlindGitAdd(cmd *syntax.CallExpr) error {
	if hasBlindGitAdd(cmd) {
		return fmt.Errorf("permission denied: blind git add commands (git add -A, git add ., git add --all, git add *) are not allowed, specify files explicitly")
	}
	return nil
}

func hasBlindGitAdd(cmd *syntax.CallExpr) bool {
	if len(cmd.Args) < 2 {
		return false
	}
	if cmd.Args[0].Lit() != "git" {
		return false
	}

	// Find the 'add' subcommand
	addIndex := -1
	for i, arg := range cmd.Args {
		if arg.Lit() == "add" {
			addIndex = i
			break
		}
	}

	if addIndex < 0 {
		return false
	}

	// Check arguments after 'add' for blind patterns
	for i := addIndex + 1; i < len(cmd.Args); i++ {
		arg := cmd.Args[i].Lit()
		// Check for blind add patterns
		if arg == "-A" || arg == "--all" || arg == "." || arg == "*" {
			return true
		}
	}

	return false
}

// isGitCommitCommand checks if a command is 'git commit'.
func isGitCommitCommand(cmd *syntax.CallExpr) bool {
	if len(cmd.Args) < 2 {
		return false
	}

	// First argument must be 'git'
	if cmd.Args[0].Lit() != "git" {
		return false
	}

	// Look for 'commit' in any position after 'git'
	for i := 1; i < len(cmd.Args); i++ {
		if cmd.Args[i].Lit() == "commit" {
			return true
		}
	}

	return false
}
