/*
	Types and functions to help with testing code that uses exec.Run.
*/
package exec

import (
	"regexp"
	"sync"
)

// CommandCollector collects arguments to the Run method for later inspection. Safe for use in
// multiple goroutines as long as the function passed to SetDelegateRun is.
// Example usage:
// 	mock := CommandCollector{}
//	SetRunForTesting(mock.Run)
//	defer SetRunForTesting(DefaultRun)
//	err := Run(&Command{
//		Name: "touch",
//		Args: []string{"/tmp/file"},
//	})
//	assert.Equal(t, "touch /tmp/file"", DebugString(mock.Commands()[0]))
type CommandCollector struct {
	mutex       sync.RWMutex
	commands    []*Command
	delegateRun func(*Command) error
}

func (c *CommandCollector) Commands() []*Command {
	c.mutex.RLock()
	defer c.mutex.RUnlock()
	// TODO(benjaminwagner): Can I just return c.commands?
	result := make([]*Command, len(c.commands))
	copy(result, c.commands)
	return result
}

func (c *CommandCollector) ClearCommands() {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.commands = nil
}

func (c *CommandCollector) SetDelegateRun(delegateRun func(*Command) error) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.delegateRun = delegateRun
}

// Collects command into c and delegates to the function specified by SetDelegateRun. Returns nil
// if SetDelegateRun has not been called. The command will be visible in Commands() before the
// SetDelegateRun function is called.
func (c *CommandCollector) Run(command *Command) error {
	c.mutex.Lock()
	c.commands = append(c.commands, command)
	delegateRun := c.delegateRun
	c.mutex.Unlock()
	if delegateRun == nil {
		return nil
	} else {
		return delegateRun(command)
	}
}

// Provides a Run method that returns based on regexp matches of DebugString(command). Safe for use
// in multiple goroutines.
// Example usage:
// 	mock := MockRun{}
//	SetRunForTesting(mock.Run)
//	defer SetRunForTesting(DefaultRun)
//	mock.AddRule("touch /tmp/bar", fmt.Errorf("baz"))
//	assert.NoError(t, Run(&Command{
//		Name: "touch",
//		Args: []string{"/tmp/foo"},
//	}))
//	err := Run(&Command{
//		Name: "touch",
//		Args: []string{"/tmp/bar"},
//	})
//	assert.Error(t, err)
//	assert.Contains(t, err.Error(), "baz")
type MockRun struct {
	mutex    sync.RWMutex
	matchers []*regexp.Regexp
	results  []error
}

// Panics if expr is not a valid regexp.
func (m *MockRun) AddRule(expr string, err error) {
	m.mutex.Lock()
	defer m.mutex.Unlock()
	m.matchers = append(m.matchers, regexp.MustCompile(expr))
	m.results = append(m.results, err)
}

// Tries to match DebugString(command) against the regexps in the order of the calls to AddRule,
// with the first matched giving the return value. Returns nil if no regexps match.
func (m *MockRun) Run(command *Command) error {
	m.mutex.RLock()
	defer m.mutex.RUnlock()
	commandStr := DebugString(command)
	for i, matcher := range m.matchers {
		if matcher.FindStringIndex(commandStr) != nil {
			return m.results[i]
		}
	}
	return nil
}
