package main

// ExitCodeType describes how to match a command's exit code.
type ExitCodeType int

const (
	ExitCodeNone     ExitCodeType = iota // not specified — expect 0
	ExitCodeExact                        // expect specific code
	ExitCodeWildcard                     // [*] — expect any non-zero
)

func exitCodeOK(ecType ExitCodeType, ecValue int, actual int) bool {
	switch ecType {
	case ExitCodeNone:
		return actual == 0
	case ExitCodeWildcard:
		return actual != 0
	case ExitCodeExact:
		return actual == ecValue
	default:
		return actual == 0
	}
}

type Command struct {
	Line          int
	Raw           string
	Cmd           string
	Expected      []string
	ExitCodeType  ExitCodeType
	ExitCodeValue int
}

type Directive struct {
	Type  string // "setup" or "env"
	Path  string // for setup
	Key   string // for env
	Value string // for env
	Line  int
}

type ShoutFile struct {
	Path       string
	Commands   []Command
	Directives []Directive
}

type CommandResult struct {
	Command  Command
	Actual   []string
	ExitCode int
}

type FileResult struct {
	File    ShoutFile
	Results []CommandResult
	TmpDir  string
	Error   string
}

type DiffLine struct {
	Kind string // "equal", "expected", "actual", "context"
	Text string
}

type TestResult struct {
	Path         string
	Passed       bool
	CommandCount int
	Failures     []FailedCommand
	Error        string
}

type FailedCommand struct {
	Result           CommandResult
	DiffLines        []DiffLine
	ExitCodeMismatch bool
}
