// Copyright 2015 Google Inc. All rights reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package kati

import (
	"fmt"
	"os/exec"
	"strings"
	"sync"
)

type execContext struct {
	shell string

	mu     sync.Mutex
	ev     *Evaluator
	output string
	inputs []string
}

func newExecContext(vars Vars, avoidIO bool) *execContext {
	ev := NewEvaluator(vars)
	ev.avoidIO = avoidIO

	ctx := &execContext{
		ev: ev,
	}
	av := autoVar{ctx: ctx}
	for k, v := range map[string]Var{
		"@": autoAtVar{autoVar: av},
		"<": autoLessVar{autoVar: av},
		"^": autoHatVar{autoVar: av},
		"+": autoPlusVar{autoVar: av},
		"*": autoStarVar{autoVar: av},
	} {
		ev.vars[k] = v
		// $<k>D = $(patsubst %/,%,$(dir $<k>))
		ev.vars[k+"D"] = suffixDVar(k)
		// $<k>F = $(notdir $<k>)
		ev.vars[k+"F"] = suffixFVar(k)
	}

	// TODO: We should move this to somewhere around evalCmd so that
	// we can handle SHELL in target specific variables.
	shell, err := ev.EvaluateVar("SHELL")
	if err != nil {
		shell = "/bin/sh"
	}
	ctx.shell = shell
	return ctx
}

func (ec *execContext) uniqueInputs() []string {
	var uniqueInputs []string
	seen := make(map[string]bool)
	for _, input := range ec.inputs {
		if !seen[input] {
			seen[input] = true
			uniqueInputs = append(uniqueInputs, input)
		}
	}
	return uniqueInputs
}

type autoVar struct{ ctx *execContext }

func (v autoVar) Flavor() string  { return "undefined" }
func (v autoVar) Origin() string  { return "automatic" }
func (v autoVar) IsDefined() bool { return true }
func (v autoVar) Append(*Evaluator, string) (Var, error) {
	return nil, fmt.Errorf("cannot append to autovar")
}
func (v autoVar) AppendVar(*Evaluator, Value) (Var, error) {
	return nil, fmt.Errorf("cannot append to autovar")
}
func (v autoVar) serialize() serializableVar {
	return serializableVar{Type: ""}
}
func (v autoVar) dump(d *dumpbuf) {
	d.err = fmt.Errorf("cannot dump auto var: %v", v)
}

type autoAtVar struct{ autoVar }

func (v autoAtVar) Eval(w evalWriter, ev *Evaluator) error {
	fmt.Fprint(w, v.String())
	return nil
}
func (v autoAtVar) String() string { return v.ctx.output }

type autoLessVar struct{ autoVar }

func (v autoLessVar) Eval(w evalWriter, ev *Evaluator) error {
	fmt.Fprint(w, v.String())
	return nil
}
func (v autoLessVar) String() string {
	if len(v.ctx.inputs) > 0 {
		return v.ctx.inputs[0]
	}
	return ""
}

type autoHatVar struct{ autoVar }

func (v autoHatVar) Eval(w evalWriter, ev *Evaluator) error {
	fmt.Fprint(w, v.String())
	return nil
}
func (v autoHatVar) String() string {
	return strings.Join(v.ctx.uniqueInputs(), " ")
}

type autoPlusVar struct{ autoVar }

func (v autoPlusVar) Eval(w evalWriter, ev *Evaluator) error {
	fmt.Fprint(w, v.String())
	return nil
}
func (v autoPlusVar) String() string { return strings.Join(v.ctx.inputs, " ") }

type autoStarVar struct{ autoVar }

func (v autoStarVar) Eval(w evalWriter, ev *Evaluator) error {
	fmt.Fprint(w, v.String())
	return nil
}

// TODO: Use currentStem. See auto_stem_var.mk
func (v autoStarVar) String() string { return stripExt(v.ctx.output) }

func suffixDVar(k string) Var {
	return &recursiveVar{
		expr: expr{
			&funcPatsubst{
				fclosure: fclosure{
					args: []Value{
						literal("(patsubst"),
						literal("%/"),
						literal("%"),
						&funcDir{
							fclosure: fclosure{
								args: []Value{
									literal("(dir"),
									&varref{
										varname: literal(k),
									},
								},
							},
						},
					},
				},
			},
		},
		origin: "automatic",
	}
}

func suffixFVar(k string) Var {
	return &recursiveVar{
		expr: expr{
			&funcNotdir{
				fclosure: fclosure{
					args: []Value{
						literal("(notdir"),
						&varref{varname: literal(k)},
					},
				},
			},
		},
		origin: "automatic",
	}
}

// runner is a single shell command invocation.
type runner struct {
	output      string
	cmd         string
	echo        bool
	ignoreError bool
	shell       string
}

func (r runner) String() string {
	cmd := r.cmd
	if !r.echo {
		cmd = "@" + cmd
	}
	if r.ignoreError {
		cmd = "-" + cmd
	}
	return cmd
}

func (r runner) forCmd(s string) runner {
	for {
		s = trimLeftSpace(s)
		if s == "" {
			return runner{}
		}
		switch s[0] {
		case '@':
			if !DryRunFlag {
				r.echo = false
			}
			s = s[1:]
			continue
		case '-':
			r.ignoreError = true
			s = s[1:]
			continue
		}
		break
	}
	r.cmd = s
	return r
}

func (r runner) eval(ev *Evaluator, s string) ([]runner, error) {
	r = r.forCmd(s)
	if strings.IndexByte(r.cmd, '$') < 0 {
		// fast path
		return []runner{r}, nil
	}
	// TODO(ukai): parse once more earlier?
	expr, _, err := parseExpr([]byte(r.cmd), nil, parseOp{})
	if err != nil {
		return nil, ev.errorf("parse cmd %q: %v", r.cmd, err)
	}
	buf := newBuf()
	err = expr.Eval(buf, ev)
	if err != nil {
		return nil, err
	}
	cmds := buf.String()
	freeBuf(buf)
	logf("evalcmd: %q => %q", r.cmd, cmds)
	var runners []runner
	for _, cmd := range strings.Split(cmds, "\n") {
		if len(runners) > 0 && strings.HasSuffix(runners[len(runners)-1].cmd, "\\") {
			runners[len(runners)-1].cmd += "\n"
			runners[len(runners)-1].cmd += cmd
			continue
		}
		runners = append(runners, r.forCmd(cmd))
	}
	return runners, nil
}

func (r runner) run(output string) error {
	if r.echo || DryRunFlag {
		fmt.Printf("%s\n", r.cmd)
	}
	if DryRunFlag {
		return nil
	}
	args := []string{r.shell, "-c", cmdline(r.cmd)}
	cmd := exec.Cmd{
		Path: args[0],
		Args: args,
	}
	out, err := cmd.CombinedOutput()
	fmt.Printf("%s", out)
	exit := exitStatus(err)
	if r.ignoreError && exit != 0 {
		fmt.Printf("[%s] Error %d (ignored)\n", output, exit)
		err = nil
	}
	return err
}

func createRunners(ctx *execContext, n *DepNode) ([]runner, bool, error) {
	var runners []runner
	if len(n.Cmds) == 0 {
		return runners, false, nil
	}

	ctx.mu.Lock()
	defer ctx.mu.Unlock()
	// For automatic variables.
	ctx.output = n.Output
	ctx.inputs = n.ActualInputs
	for k, v := range n.TargetSpecificVars {
		restore := ctx.ev.vars.save(k)
		defer restore()
		ctx.ev.vars[k] = v
		logf("set tsv: %s=%s", k, v)
	}

	ctx.ev.filename = n.Filename
	ctx.ev.lineno = n.Lineno
	logf("Building: %s cmds:%q", n.Output, n.Cmds)
	r := runner{
		output: n.Output,
		echo:   true,
		shell:  ctx.shell,
	}
	for _, cmd := range n.Cmds {
		rr, err := r.eval(ctx.ev, cmd)
		if err != nil {
			return nil, false, err
		}
		for _, r := range rr {
			if len(r.cmd) != 0 {
				runners = append(runners, r)
			}
		}
	}
	return runners, ctx.ev.hasIO, nil
}

func evalCommands(nodes []*DepNode, vars Vars) error {
	ioCnt := 0
	ectx := newExecContext(vars, true)
	for i, n := range nodes {
		runners, hasIO, err := createRunners(ectx, n)
		if err != nil {
			return err
		}
		if hasIO {
			ioCnt++
			if ioCnt%100 == 0 {
				logStats("%d/%d rules have IO", ioCnt, i+1)
			}
			continue
		}

		n.Cmds = []string{}
		n.TargetSpecificVars = make(Vars)
		for _, r := range runners {
			n.Cmds = append(n.Cmds, r.String())
		}
	}
	logStats("%d/%d rules have IO", ioCnt, len(nodes))
	return nil
}
