// 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"
	"io"
	"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 io.Writer, 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 io.Writer, 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 io.Writer, 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 io.Writer, 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 io.Writer, 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)
	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", 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("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
}
