// 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 (
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
)

type ninjaGenerator struct {
	f       *os.File
	nodes   []*DepNode
	vars    Vars
	exports map[string]bool
	ex      *Executor
	ruleID  int
	done    map[string]bool
	ccRe    *regexp.Regexp
	gomaDir string
}

func newNinjaGenerator(g *DepGraph, gomaDir string) *ninjaGenerator {
	ccRe, err := regexp.Compile(`^prebuilts/(gcc|clang)/.*(gcc|g\+\+|clang|clang\+\+) .* -c `)
	if err != nil {
		panic(err)
	}
	return &ninjaGenerator{
		nodes:   g.nodes,
		vars:    g.vars,
		exports: g.exports,
		done:    make(map[string]bool),
		ccRe:    ccRe,
		gomaDir: gomaDir,
	}
}

func getDepfileImpl(ss string) (string, error) {
	tss := ss + " "
	if !strings.Contains(tss, " -MD ") && !strings.Contains(tss, " -MMD ") {
		return "", nil
	}

	mfIndex := strings.Index(ss, " -MF ")
	if mfIndex >= 0 {
		mf := trimLeftSpace(ss[mfIndex+4:])
		if strings.Index(mf, " -MF ") >= 0 {
			return "", fmt.Errorf("Multiple output file candidates in %s", ss)
		}
		mfEndIndex := strings.IndexAny(mf, " \t\n")
		if mfEndIndex >= 0 {
			mf = mf[:mfEndIndex]
		}

		return mf, nil
	}

	outIndex := strings.Index(ss, " -o ")
	if outIndex < 0 {
		return "", fmt.Errorf("Cannot find the depfile in %s", ss)
	}
	out := trimLeftSpace(ss[outIndex+4:])
	if strings.Index(out, " -o ") >= 0 {
		return "", fmt.Errorf("Multiple output file candidates in %s", ss)
	}
	outEndIndex := strings.IndexAny(out, " \t\n")
	if outEndIndex >= 0 {
		out = out[:outEndIndex]
	}
	return stripExt(out) + ".d", nil
}

func getDepfile(ss string) (string, error) {
	// A hack for Android - llvm-rs-cc seems not to emit a dep file.
	if strings.Contains(ss, "bin/llvm-rs-cc ") {
		return "", nil
	}

	r, err := getDepfileImpl(ss)
	if r == "" || err != nil {
		return r, err
	}

	// A hack for Makefiles generated by automake.
	mvCmd := "(mv -f " + r + " "
	if i := strings.LastIndex(ss, mvCmd); i >= 0 {
		rest := ss[i+len(mvCmd):]
		ei := strings.IndexByte(rest, ')')
		if ei < 0 {
			panic(ss)
		}
		return rest[:ei], nil
	}

	// A hack for Android to get .P files instead of .d.
	p := stripExt(r) + ".P"
	if strings.Contains(ss, p) {
		return p, nil
	}

	// A hack for Android. For .s files, GCC does not use
	// C preprocessor, so it ignores -MF flag.
	as := "/" + stripExt(filepath.Base(r)) + ".s"
	if strings.Contains(ss, as) {
		return "", nil
	}

	return r, nil
}

func stripShellComment(s string) string {
	if strings.IndexByte(s, '#') < 0 {
		// Fast path.
		return s
	}
	var escape bool
	var quote rune
	for i, c := range s {
		if quote > 0 {
			if quote == c && (quote == '\'' || !escape) {
				quote = 0
			}
		} else if !escape {
			if c == '#' {
				return s[:i]
			} else if c == '\'' || c == '"' || c == '`' {
				quote = c
			}
		}
		if escape {
			escape = false
		} else if c == '\\' {
			escape = true
		} else {
			escape = false
		}
	}
	return s
}

func (n *ninjaGenerator) genShellScript(runners []runner) (string, bool) {
	useGomacc := false
	var buf bytes.Buffer
	for i, r := range runners {
		if i > 0 {
			if runners[i-1].ignoreError {
				buf.WriteString(" ; ")
			} else {
				buf.WriteString(" && ")
			}
		}
		cmd := stripShellComment(r.cmd)
		cmd = trimLeftSpace(cmd)
		cmd = strings.Replace(cmd, "\\\n", " ", -1)
		cmd = strings.TrimRight(cmd, " \t\n;")
		cmd = strings.Replace(cmd, "$", "$$", -1)
		cmd = strings.Replace(cmd, "\t", " ", -1)
		if cmd == "" {
			cmd = "true"
		}
		if n.gomaDir != "" && n.ccRe.MatchString(cmd) {
			cmd = fmt.Sprintf("%s/gomacc %s", n.gomaDir, cmd)
			useGomacc = true
		}

		needsSubShell := i > 0 || len(runners) > 1
		if cmd[0] == '(' {
			needsSubShell = false
		}

		if needsSubShell {
			buf.WriteByte('(')
		}
		buf.WriteString(cmd)
		if i == len(runners)-1 && r.ignoreError {
			buf.WriteString(" ; true")
		}
		if needsSubShell {
			buf.WriteByte(')')
		}
	}
	return buf.String(), n.gomaDir != "" && !useGomacc
}

func (n *ninjaGenerator) genRuleName() string {
	ruleName := fmt.Sprintf("rule%d", n.ruleID)
	n.ruleID++
	return ruleName
}

func (n *ninjaGenerator) emitBuild(output, rule, dep string) {
	fmt.Fprintf(n.f, "build %s: %s%s\n", output, rule, dep)
}

func getDepString(node *DepNode) string {
	var deps []string
	var orderOnlys []string
	for _, d := range node.Deps {
		if d.IsOrderOnly {
			orderOnlys = append(orderOnlys, d.Output)
		} else {
			deps = append(deps, d.Output)
		}
	}
	dep := ""
	if len(deps) > 0 {
		dep += fmt.Sprintf(" %s", strings.Join(deps, " "))
	}
	if len(orderOnlys) > 0 {
		dep += fmt.Sprintf(" || %s", strings.Join(orderOnlys, " "))
	}
	return dep
}

func (n *ninjaGenerator) emitNode(node *DepNode) {
	if n.done[node.Output] {
		return
	}
	n.done[node.Output] = true

	if len(node.Cmds) == 0 && len(node.Deps) == 0 && !node.IsPhony {
		return
	}

	runners, _ := n.ex.createRunners(node, true)
	ruleName := "phony"
	useLocalPool := false
	if len(runners) > 0 {
		ruleName = n.genRuleName()
		fmt.Fprintf(n.f, "rule %s\n", ruleName)
		fmt.Fprintf(n.f, " description = build $out\n")

		ss, ulp := n.genShellScript(runners)
		if ulp {
			useLocalPool = true
		}
		depfile, err := getDepfile(ss)
		if err != nil {
			panic(err)
		}
		if depfile != "" {
			fmt.Fprintf(n.f, " depfile = %s\n", depfile)
		}
		// It seems Linux is OK with ~130kB.
		// TODO: Find this number automatically.
		ArgLenLimit := 100 * 1000
		if len(ss) > ArgLenLimit {
			fmt.Fprintf(n.f, " rspfile = $out.rsp\n")
			fmt.Fprintf(n.f, " rspfile_content = %s\n", ss)
			ss = "sh $out.rsp"
		}
		fmt.Fprintf(n.f, " command = %s\n", ss)

	}
	n.emitBuild(node.Output, ruleName, getDepString(node))
	if useLocalPool {
		fmt.Fprintf(n.f, " pool = local_pool\n")
	}

	for _, d := range node.Deps {
		n.emitNode(d)
	}
}

func (n *ninjaGenerator) generateShell() {
	f, err := os.Create("ninja.sh")
	if err != nil {
		panic(err)
	}
	defer f.Close()

	ev := NewEvaluator(n.vars)
	shell := ev.EvaluateVar("SHELL")
	if shell == "" {
		shell = "/bin/sh"
	}
	fmt.Fprintf(f, "#!%s\n", shell)
	for name, export := range n.exports {
		if export {
			fmt.Fprintf(f, "export %s=%s\n", name, ev.EvaluateVar(name))
		} else {
			fmt.Fprintf(f, "unset %s\n", name)
		}
	}
	if n.gomaDir == "" {
		fmt.Fprintln(f, `exec ninja "$@"`)
	} else {
		fmt.Fprintln(f, `exec ninja -j300 "$@"`)
	}

	err = f.Chmod(0755)
	if err != nil {
		panic(err)
	}
}

func (n *ninjaGenerator) generateNinja() {
	f, err := os.Create("build.ninja")
	if err != nil {
		panic(err)
	}
	defer f.Close()

	n.f = f
	fmt.Fprintf(n.f, "# Generated by kati\n")
	fmt.Fprintf(n.f, "\n")

	if n.gomaDir != "" {
		fmt.Fprintf(n.f, "pool local_pool\n")
		fmt.Fprintf(n.f, " depth = %d\n", runtime.NumCPU())
	}

	n.ex = NewExecutor(n.vars, nil)
	for _, node := range n.nodes {
		n.emitNode(node)
	}
}

func GenerateNinja(g *DepGraph, gomaDir string) {
	n := newNinjaGenerator(g, gomaDir)
	n.generateShell()
	n.generateNinja()
}
