package main

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

type EvalResult struct {
	vars  Vars
	rules []*Rule
}

type Evaluator struct {
	outVars  Vars
	outRules []*Rule
	vars     Vars
	lastRule *Rule

	filename string
	lineno   int
}

func newEvaluator(vars map[string]Var) *Evaluator {
	return &Evaluator{
		outVars: make(Vars),
		vars:    vars,
	}
}

func (ev *Evaluator) Value(v Value) []byte {
	var buf bytes.Buffer
	v.Eval(&buf, ev)
	return buf.Bytes()
}

// TODO(ukai): use unicode.IsSpace?
func isWhitespace(b byte) bool {
	switch b {
	case ' ', '\t', '\n', '\r':
		return true
	}
	return false
}

func (ev *Evaluator) Values(v Value) [][]byte {
	var buf bytes.Buffer
	v.Eval(&buf, ev)
	val := buf.Bytes()
	var values [][]byte
	b := -1
	for i := 0; i < len(val); i++ {
		if b < 0 {
			if isWhitespace(val[i]) {
				continue
			}
			b = i
		} else {
			if isWhitespace(val[i]) {
				values = append(values, val[b:i])
				b = -1
				continue
			}
		}
	}
	if b >= 0 {
		values = append(values, val[b:])
	}
	return values
}

// TODO(ukai): deprecated.
func (ev *Evaluator) evalExpr(ex string) string {
	v, _, err := parseExpr([]byte(ex), nil)
	if err != nil {
		panic(err)
	}
	return string(ev.Value(v))
}

func (ev *Evaluator) evalAssign(ast *AssignAST) {
	ev.lastRule = nil
	lhs, rhs := ev.evalAssignAST(ast)
	Log("ASSIGN: %s=%q (flavor:%q)", lhs, rhs, rhs.Flavor())
	if len(lhs) == 0 {
		Error(ast.filename, ast.lineno, "*** empty variable name.")
	}
	ev.outVars.Assign(lhs, rhs)
}

func (ev *Evaluator) evalAssignAST(ast *AssignAST) (string, Var) {
	ev.filename = ast.filename
	ev.lineno = ast.lineno

	lhs := strings.TrimSpace(ev.evalExpr(ast.lhs))
	rhs := ast.evalRHS(ev, lhs)
	return lhs, rhs
}

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

	expr := ast.expr
	if ast.semicolonIndex >= 0 {
		expr = expr[0:ast.semicolonIndex]
	}
	line := ev.evalExpr(expr)
	Log("rule? %q=>%q", expr, line)

	// See semicolon.mk.
	if strings.TrimRight(line, " \t\n;") == "" {
		return
	}

	rule := &Rule{
		filename: ast.filename,
		lineno:   ast.lineno,
	}
	assign, err := rule.parse(line)
	if err != nil {
		Error(ast.filename, ast.lineno, "%v", err.Error())
	}
	Log("rule %q => outputs:%q, inputs:%q", line, rule.outputs, rule.inputs)

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

	if assign != nil {
		if ast.semicolonIndex >= 0 {
			assign, err = rule.parse(ev.evalExpr(ast.expr))
			if err != nil {
				Error(ast.filename, ast.lineno, "%v", err.Error())
			}
		}
		rule.vars = NewVarTab(nil)
		lhs, rhs := ev.evalAssignAST(assign)
		Log("rule outputs:%q assign:%q=%q (flavor:%q)", rule.outputs, lhs, rhs, rhs.Flavor())
		rule.vars.Assign(lhs, rhs)
	} else {
		if ast.semicolonIndex > 0 {
			rule.cmds = append(rule.cmds, ast.expr[ast.semicolonIndex+1:])
		}
		Log("rule outputs:%q cmds:%q", rule.outputs, rule.cmds)
	}
	ev.lastRule = rule
	ev.outRules = append(ev.outRules, rule)
}

func (ev *Evaluator) evalCommand(ast *CommandAST) {
	ev.filename = ast.filename
	ev.lineno = ast.lineno
	if ev.lastRule == nil {
		// This could still be an assignment statement. See
		// assign_after_tab.mk.
		if strings.IndexByte(ast.cmd, '=') >= 0 {
			line := strings.TrimLeft(ast.cmd, " \t")
			mk, err := ParseMakefileString(line, ast.filename, ast.lineno)
			if err != nil {
				panic(err)
			}
			if len(mk.stmts) == 1 && mk.stmts[0].(*AssignAST) != nil {
				ev.eval(mk.stmts[0])
			}
			return
		}
		Error(ast.filename, ast.lineno, "*** commands commence before first target.")
	}
	ev.lastRule.cmds = append(ev.lastRule.cmds, ast.cmd)
	if ev.lastRule.cmdLineno == 0 {
		ev.lastRule.cmdLineno = ast.lineno
	}
}

func (ev *Evaluator) LookupVar(name string) Var {
	v := ev.outVars.Lookup(name)
	if v.IsDefined() {
		return v
	}
	return ev.vars.Lookup(name)
}

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

	// TODO: Handle glob
	v, _, err := parseExpr([]byte(ast.expr), nil)
	if err != nil {
		panic(err)
	}
	files := ev.Values(v)
	for _, f := range files {
		file := string(f)
		Log("Reading makefile `%s'", file)
		mk, err := ParseMakefile(file)
		if err != nil {
			if ast.op == "include" {
				panic(err)
			} else {
				continue
			}
		}

		makefileList := ev.outVars.Lookup("MAKEFILE_LIST")
		makefileList = makefileList.Append(ev, mk.filename)
		ev.outVars.Assign("MAKEFILE_LIST", makefileList)

		for _, stmt := range mk.stmts {
			ev.eval(stmt)
		}

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

			for k, v := range er.vars.Vars() {
				ev.outVars.Assign(k, v)
			}
			for _, r := range er.rules {
				ev.outRules = append(ev.outRules, r)
			}
		*/
	}
}

func (ev *Evaluator) evalIf(ast *IfAST) {
	var isTrue bool
	switch ast.op {
	case "ifdef", "ifndef":
		vname := ev.evalExpr(ast.lhs)
		v := ev.LookupVar(string(vname))
		value := ev.Value(v)
		isTrue = (len(value) > 0) == (ast.op == "ifdef")
		Log("%s lhs=%q value=%q => %t", ast.op, ast.lhs, value, isTrue)
	case "ifeq", "ifneq":
		lhs := ev.evalExpr(ast.lhs)
		rhs := ev.evalExpr(ast.rhs)
		isTrue = (lhs == rhs) == (ast.op == "ifeq")
		Log("%s lhs=%q %q rhs=%q %q => %t", ast.op, ast.lhs, lhs, ast.rhs, rhs, isTrue)
	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 Vars) (er *EvalResult, err error) {
	ev := newEvaluator(vars)
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("panic: %v", r)
		}
	}()

	makefile_list := vars.Lookup("MAKEFILE_LIST")
	makefile_list = makefile_list.Append(ev, mk.filename)
	ev.outVars.Assign("MAKEFILE_LIST", makefile_list)

	for _, stmt := range mk.stmts {
		ev.eval(stmt)
	}
	return &EvalResult{
		vars:  ev.outVars,
		rules: ev.outRules,
	}, nil
}
