// 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"
	"time"
)

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) {
	startTime := time.Now()
	n := newNinjaGenerator(g, gomaDir)
	n.generateShell()
	n.generateNinja()
	logStats("generate ninja time: %q", time.Since(startTime))
}
