package builder

// This will take a single word and an array of env variables and
// process all quotes (" and ') as well as $xxx and ${xxx} env variable
// tokens.  Tries to mimic bash shell process.
// It doesn't support all flavors of ${xx:...} formats but new ones can
// be added by adding code to the "special ${} format processing" section

import (
	"fmt"
	"strings"
	"unicode"
)

type shellWord struct {
	word string
	envs []string
	pos  int
}

// ProcessWord will use the 'env' list of environment variables,
// and replace any env var references in 'word'.
func ProcessWord(word string, env []string) (string, error) {
	sw := &shellWord{
		word: word,
		envs: env,
		pos:  0,
	}
	return sw.process()
}

func (sw *shellWord) process() (string, error) {
	return sw.processStopOn('\000')
}

// Process the word, starting at 'pos', and stop when we get to the
// end of the word or the 'stopChar' character
func (sw *shellWord) processStopOn(stopChar rune) (string, error) {
	var result string
	var charFuncMapping = map[rune]func() (string, error){
		'\'': sw.processSingleQuote,
		'"':  sw.processDoubleQuote,
		'$':  sw.processDollar,
	}

	for sw.pos < len(sw.word) {
		ch := sw.peek()
		if stopChar != '\000' && ch == stopChar {
			sw.next()
			break
		}
		if fn, ok := charFuncMapping[ch]; ok {
			// Call special processing func for certain chars
			tmp, err := fn()
			if err != nil {
				return "", err
			}
			result += tmp
		} else {
			// Not special, just add it to the result
			ch = sw.next()
			if ch == '\\' {
				// '\' escapes, except end of line
				ch = sw.next()
				if ch == '\000' {
					continue
				}
			}
			result += string(ch)
		}
	}

	return result, nil
}

func (sw *shellWord) peek() rune {
	if sw.pos == len(sw.word) {
		return '\000'
	}
	return rune(sw.word[sw.pos])
}

func (sw *shellWord) next() rune {
	if sw.pos == len(sw.word) {
		return '\000'
	}
	ch := rune(sw.word[sw.pos])
	sw.pos++
	return ch
}

func (sw *shellWord) processSingleQuote() (string, error) {
	// All chars between single quotes are taken as-is
	// Note, you can't escape '
	var result string

	sw.next()

	for {
		ch := sw.next()
		if ch == '\000' || ch == '\'' {
			break
		}
		result += string(ch)
	}
	return result, nil
}

func (sw *shellWord) processDoubleQuote() (string, error) {
	// All chars up to the next " are taken as-is, even ', except any $ chars
	// But you can escape " with a \
	var result string

	sw.next()

	for sw.pos < len(sw.word) {
		ch := sw.peek()
		if ch == '"' {
			sw.next()
			break
		}
		if ch == '$' {
			tmp, err := sw.processDollar()
			if err != nil {
				return "", err
			}
			result += tmp
		} else {
			ch = sw.next()
			if ch == '\\' {
				chNext := sw.peek()

				if chNext == '\000' {
					// Ignore \ at end of word
					continue
				}

				if chNext == '"' || chNext == '$' {
					// \" and \$ can be escaped, all other \'s are left as-is
					ch = sw.next()
				}
			}
			result += string(ch)
		}
	}

	return result, nil
}

func (sw *shellWord) processDollar() (string, error) {
	sw.next()
	ch := sw.peek()
	if ch == '{' {
		sw.next()
		name := sw.processName()
		ch = sw.peek()
		if ch == '}' {
			// Normal ${xx} case
			sw.next()
			return sw.getEnv(name), nil
		}
		if ch == ':' {
			// Special ${xx:...} format processing
			// Yes it allows for recursive $'s in the ... spot

			sw.next() // skip over :
			modifier := sw.next()

			word, err := sw.processStopOn('}')
			if err != nil {
				return "", err
			}

			// Grab the current value of the variable in question so we
			// can use to to determine what to do based on the modifier
			newValue := sw.getEnv(name)

			switch modifier {
			case '+':
				if newValue != "" {
					newValue = word
				}
				return newValue, nil

			case '-':
				if newValue == "" {
					newValue = word
				}
				return newValue, nil

			default:
				return "", fmt.Errorf("Unsupported modifier (%c) in substitution: %s", modifier, sw.word)
			}
		}
		return "", fmt.Errorf("Missing ':' in substitution: %s", sw.word)
	}
	// $xxx case
	name := sw.processName()
	if name == "" {
		return "$", nil
	}
	return sw.getEnv(name), nil
}

func (sw *shellWord) processName() string {
	// Read in a name (alphanumeric or _)
	// If it starts with a numeric then just return $#
	var name string

	for sw.pos < len(sw.word) {
		ch := sw.peek()
		if len(name) == 0 && unicode.IsDigit(ch) {
			ch = sw.next()
			return string(ch)
		}
		if !unicode.IsLetter(ch) && !unicode.IsDigit(ch) && ch != '_' {
			break
		}
		ch = sw.next()
		name += string(ch)
	}

	return name
}

func (sw *shellWord) getEnv(name string) string {
	for _, env := range sw.envs {
		i := strings.Index(env, "=")
		if i < 0 {
			if name == env {
				// Should probably never get here, but just in case treat
				// it like "var" and "var=" are the same
				return ""
			}
			continue
		}
		if name != env[:i] {
			continue
		}
		return env[i+1:]
	}
	return ""
}
