package main

import (
	"bytes"
	"fmt"
	"strings"
)

type EvalResult struct {
	vars  map[string]string
	rules []*Rule
	refs  map[string]bool
}

type Evaluator struct {
	outVars  map[string]string
	outRules []*Rule
	refs     map[string]bool
	vars     map[string]string
	curRule  *Rule

	funcs map[string]Func

	filename string
	lineno   int
}

func newEvaluator(vars map[string]string) *Evaluator {
	return &Evaluator{
		outVars: make(map[string]string),
		refs:    make(map[string]bool),
		vars:    vars,
		funcs: map[string]Func{
			"subst":    funcSubst,
			"patsubst": funcPatsubst,
			"wildcard": funcWildcard,
			"shell":    funcShell,
			"warning":  funcWarning,
		},
	}
}

func (ev *Evaluator) evalFunction(args []string) (string, bool) {
	if len(args) == 0 {
		return "", false
	}
	i := strings.IndexAny(args[0], " \t")
	if i < 0 {
		return "", false
	}
	cmd := strings.TrimSpace(args[0][:i])
	args[0] = strings.TrimLeft(args[0][i+1:], " \t")
	if f, ok := ev.funcs[cmd]; ok {
		return f(ev, args), true
	}
	return "", false
}

func (ev *Evaluator) evalExprSlice(ex string) (string, int) {
	var buf bytes.Buffer
	i := 0
Loop:
	for i < len(ex) {
		ch := ex[i]
		i++
		switch ch {
		case '$':
			if i >= len(ex) {
				break Loop
			}

			var varname string
			switch ex[i] {
			case '@', '$':
				buf.WriteByte('$')
				buf.WriteByte(ex[i])
				i++
				continue
			case '(', '{':
				args, rest, err := parseExpr(ex[i:])
				if err != nil {
				}
				i += rest
				if r, done := ev.evalFunction(args); done {
					buf.WriteString(r)
					continue
				}

				varname = strings.Join(args, ",")
			default:
				varname = string(ex[i])
				i++
			}

			value, present := ev.vars[varname]
			if !present {
				ev.refs[varname] = true
				value = ev.outVars[varname]
			}
			buf.WriteString(ev.evalExpr(value))

		default:
			buf.WriteByte(ch)
		}
	}
	return buf.String(), i
}

func (ev *Evaluator) evalExprCommand(ex string) string {
	r, i := ev.evalExprSlice(ex)
	if len(ex) != i {
		panic(fmt.Sprintf("Had a null character? %q, %d", ex, i))
	}
	return r
}

func expandCommandVars(cmd string, output string) string {
	// Fast path.
	if strings.IndexByte(cmd, '$') < 0 {
		return cmd
	}

	var buf bytes.Buffer
	i := 0
	for i < len(cmd) {
		ch := cmd[i]
		i++
		if ch != '$' || i >= len(cmd) {
			buf.WriteByte(ch)
			continue
		}
		switch cmd[i] {
		case '@':
			buf.WriteString(output)
		case '$':
			buf.WriteByte('$')
		default:
			panic(fmt.Sprintf("TODO: not implemented yet: $%c", cmd[i]))
		}
		i++
	}
	return buf.String()
}

func (ev *Evaluator) evalExpr(ex string) string {
	ex = ev.evalExprCommand(ex)
	return expandCommandVars(ex, "")
}

func (ev *Evaluator) evalAssign(ast *AssignAST) {
	ev.filename = ast.filename
	ev.lineno = ast.lineno

	lhs := ev.evalExpr(ast.lhs)
	rhs := ast.evalRHS(ev, lhs)
	Log("ASSIGN: %s=%s", lhs, rhs)
	ev.outVars[lhs] = rhs
}

func (ev *Evaluator) evalMaybeRule(ast *MaybeRuleAST) {
	ev.filename = ast.filename
	ev.lineno = ast.lineno

	line := ev.evalExpr(ast.expr)

	if strings.TrimSpace(line) == "" {
		if len(ast.cmds) > 0 {
			Error(ast.filename, ast.cmdLineno, "*** commands commence before first target.")
		}
		return
	}

	ev.curRule = &Rule{
		filename:  ast.filename,
		lineno:    ast.lineno,
		cmdLineno: ast.cmdLineno,
	}
	if err := ev.curRule.parse(line); err != "" {
		Error(ast.filename, ast.lineno, err)
	}
	// It seems rules with no outputs are siliently ignored.
	if len(ev.curRule.outputs) == 0 {
		ev.curRule = nil
		return
	}

	var cmds []string
	for _, cmd := range ast.cmds {
		cmds = append(cmds, ev.evalExprCommand(cmd))
	}

	// TODO: Pretty print.
	//Log("RULE: %s=%s (%d commands)", lhs, rhs, len(cmds))

	ev.curRule.cmds = cmds
	ev.outRules = append(ev.outRules, ev.curRule)
	ev.curRule = nil
}

/*
func (ev *Evaluator) evalRawExpr(ast *RawExprAST) {
	ev.filename = ast.filename
	ev.lineno = ast.lineno

	result := ev.evalExpr(ast.expr)
	if result != "" {
		// TODO: Fix rule_in_var.mk.
		Error(ast.filename, ast.lineno, "*** missing separator.")
	}
}
*/

func (ev *Evaluator) getVar(name string) (string, bool) {
	value, present := ev.outVars[name]
	if present {
		return value, true
	}
	value, present = ev.vars[name]
	if present {
		return value, true
	}
	return "", false
}

func (ev *Evaluator) getVars() map[string]string {
	vars := make(map[string]string)
	for k, v := range ev.vars {
		vars[k] = v
	}
	for k, v := range ev.outVars {
		vars[k] = v
	}
	return vars
}

func (ev *Evaluator) evalInclude(ast *IncludeAST) {
	ev.filename = ast.filename
	ev.lineno = ast.lineno

	// TODO: Handle glob
	files := strings.Split(ev.evalExpr(ast.expr), " ")
	for _, file := range files {
		mk, err := ParseMakefile(file)
		if err != nil {
			if ast.op == "include" {
				panic(err)
			} else {
				continue
			}
		}

		er, err2 := Eval(mk, ev.getVars())
		if err2 != nil {
			panic(err2)
		}

		for k, v := range er.vars {
			ev.outVars[k] = v
		}
		for _, r := range er.rules {
			ev.outRules = append(ev.outRules, r)
		}
		for r, _ := range er.refs {
			ev.refs[r] = true
		}
	}
}

func (ev *Evaluator) evalIf(ast *IfAST) {
	var isTrue bool
	switch ast.op {
	case "ifdef", "ifndef":
		value, _ := ev.getVar(ev.evalExpr(ast.lhs))
		isTrue = (value != "") == (ast.op == "ifdef")
	case "ifeq", "ifneq":
		lhs := ev.evalExpr(ast.lhs)
		rhs := ev.evalExpr(ast.rhs)
		isTrue = (lhs == rhs) == (ast.op == "ifeq")
	default:
		panic(fmt.Sprintf("unknown if statement: %q", ast.op))
	}

	var stmts []AST
	if isTrue {
		stmts = ast.trueStmts
	} else {
		stmts = ast.falseStmts
	}
	for _, stmt := range stmts {
		ev.eval(stmt)
	}
}

func (ev *Evaluator) eval(ast AST) {
	ast.eval(ev)
}

func Eval(mk Makefile, vars map[string]string) (er *EvalResult, err error) {
	ev := newEvaluator(vars)
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("panic: %v", r)
		}
	}()
	for _, stmt := range mk.stmts {
		ev.eval(stmt)
	}
	return &EvalResult{
		vars:  ev.outVars,
		rules: ev.outRules,
		refs:  ev.refs,
	}, nil
}
