// 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 main

import (
	"bytes"
	"crypto/sha1"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"strings"
	"text/template"
	"time"
)

var (
	katiLogFlag           bool
	makefileFlag          string
	dryRunFlag            bool
	jobsFlag              int
	cpuprofile            string
	heapprofile           string
	memstats              string
	katiStatsFlag         bool
	katiPeriodicStatsFlag bool
	katiEvalStatsFlag     bool
	loadJSON              string
	saveJSON              string
	loadGOB               string
	saveGOB               string
	syntaxCheckOnlyFlag   bool
	queryFlag             string
	eagerCmdEvalFlag      bool
	useParaFlag           bool
	useCache              bool
	useFindCache          bool
	useWildcardCache      bool
	generateNinja         bool
	ignoreOptionalInclude string
	gomaDir               string

	katiDir string
)

type DepGraph struct {
	nodes    []*DepNode
	vars     Vars
	readMks  []*ReadMakefile
	exports  map[string]bool
	isCached bool
}

func parseFlags() {
	// TODO: Make this default and replace this by -d flag.
	flag.BoolVar(&katiLogFlag, "kati_log", false, "Verbose kati specific log")
	flag.StringVar(&makefileFlag, "f", "", "Use it as a makefile")

	flag.BoolVar(&dryRunFlag, "n", false, "Only print the commands that would be executed")

	flag.IntVar(&jobsFlag, "j", 1, "Allow N jobs at once.")

	flag.StringVar(&loadGOB, "load", "", "")
	flag.StringVar(&saveGOB, "save", "", "")
	flag.StringVar(&loadJSON, "load_json", "", "")
	flag.StringVar(&saveJSON, "save_json", "", "")

	flag.StringVar(&cpuprofile, "kati_cpuprofile", "", "write cpu profile to `file`")
	flag.StringVar(&heapprofile, "kati_heapprofile", "", "write heap profile to `file`")
	flag.StringVar(&memstats, "kati_memstats", "", "Show memstats with given templates")
	flag.BoolVar(&katiStatsFlag, "kati_stats", false, "Show a bunch of statistics")
	flag.BoolVar(&katiPeriodicStatsFlag, "kati_periodic_stats", false, "Show a bunch of periodic statistics")
	flag.BoolVar(&katiEvalStatsFlag, "kati_eval_stats", false, "Show eval statistics")
	flag.BoolVar(&eagerCmdEvalFlag, "eager_cmd_eval", false, "Eval commands first.")
	flag.BoolVar(&useParaFlag, "use_para", false, "Use para.")
	flag.BoolVar(&syntaxCheckOnlyFlag, "c", false, "Syntax check only.")
	flag.StringVar(&queryFlag, "query", "", "Show the target info")
	// TODO: Make this default.
	flag.BoolVar(&useCache, "use_cache", false, "Use cache.")
	flag.BoolVar(&useFindCache, "use_find_cache", false, "Use find cache.")
	flag.BoolVar(&useWildcardCache, "use_wildcard_cache", true, "Use wildcard cache.")
	flag.BoolVar(&generateNinja, "ninja", false, "Generate build.ninja.")
	flag.StringVar(&ignoreOptionalInclude, "ignore_optional_include", "", "If specified, skip reading -include directives start with the specified path.")
	flag.StringVar(&gomaDir, "goma_dir", "", "If specified, use goma to build C/C++ files.")
	flag.Parse()
}

func parseCommandLine() ([]string, []string) {
	var vars []string
	var targets []string
	for _, arg := range flag.Args() {
		if strings.IndexByte(arg, '=') >= 0 {
			vars = append(vars, arg)
			continue
		}
		targets = append(targets, arg)
	}
	return vars, targets
}

func getBootstrapMakefile(targets []string) Makefile {
	bootstrap := `
CC:=cc
CXX:=g++
AR:=ar
MAKE:=kati
# Pretend to be GNU make 3.81, for compatibility.
MAKE_VERSION:=3.81
SHELL:=/bin/sh
# TODO: Add more builtin vars.

# http://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules
# The document above is actually not correct. See default.c:
# http://git.savannah.gnu.org/cgit/make.git/tree/default.c?id=4.1
.c.o:
	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<
.cc.o:
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<
# TODO: Add more builtin rules.
`
	bootstrap += fmt.Sprintf("MAKECMDGOALS:=%s\n", strings.Join(targets, " "))
	cwd, err := filepath.Abs(".")
	if err != nil {
		panic(err)
	}
	bootstrap += fmt.Sprintf("CURDIR:=%s\n", cwd)
	mk, err := ParseMakefileString(bootstrap, BootstrapMakefile, 0)
	if err != nil {
		panic(err)
	}
	return mk
}

func maybeWriteHeapProfile() {
	if heapprofile != "" {
		f, err := os.Create(heapprofile)
		if err != nil {
			panic(err)
		}
		pprof.WriteHeapProfile(f)
	}
}

func getDepGraph(clvars []string, targets []string) *DepGraph {
	startTime := time.Now()

	if loadGOB != "" {
		g := LoadDepGraph(loadGOB)
		LogStats("deserialize time: %q", time.Since(startTime))
		return g
	}
	if loadJSON != "" {
		g := LoadDepGraphFromJSON(loadJSON)
		LogStats("deserialize time: %q", time.Since(startTime))
		return g
	}

	makefile := makefileFlag
	if makefile == "" {
		makefile = GetDefaultMakefile()
	}

	if useCache {
		g := LoadDepGraphCache(makefile, targets)
		if g != nil {
			return g
		}
	}

	bmk := getBootstrapMakefile(targets)

	content, err := ioutil.ReadFile(makefile)
	if err != nil {
		panic(err)
	}
	mk, err := ParseMakefile(content, makefile)
	if err != nil {
		panic(err)
	}

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

	mk.stmts = append(bmk.stmts, mk.stmts...)

	vars := make(Vars)
	for _, env := range os.Environ() {
		kv := strings.SplitN(env, "=", 2)
		Logf("envvar %q", kv)
		if len(kv) < 2 {
			panic(fmt.Sprintf("A weird environ variable %q", kv))
		}
		vars.Assign(kv[0], RecursiveVar{
			expr:   literal(kv[1]),
			origin: "environment",
		})
	}
	vars.Assign("MAKEFILE_LIST", SimpleVar{value: []byte{}, origin: "file"})
	for _, v := range clvars {
		kv := strings.SplitN(v, "=", 2)
		Logf("cmdlinevar %q", kv)
		if len(kv) < 2 {
			panic(fmt.Sprintf("unexpected command line var %q", kv))
		}
		vars.Assign(kv[0], RecursiveVar{
			expr:   literal(kv[1]),
			origin: "command line",
		})
	}

	er, err := Eval(mk, vars)
	if err != nil {
		panic(err)
	}

	vars.Merge(er.vars)

	LogStats("eval time: %q", time.Since(startTime))
	LogStats("shell func time: %q %d", shellFuncTime, shellFuncCount)

	startTime = time.Now()
	db := NewDepBuilder(er, vars)
	LogStats("dep build prepare time: %q", time.Since(startTime))

	startTime = time.Now()
	nodes, err2 := db.Eval(targets)
	if err2 != nil {
		panic(err2)
	}
	LogStats("dep build time: %q", time.Since(startTime))
	var readMks []*ReadMakefile
	// Always put the root Makefile as the first element.
	readMks = append(readMks, &ReadMakefile{
		Filename: makefile,
		Hash:     sha1.Sum(content),
		State:    FileExists,
	})
	readMks = append(readMks, er.readMks...)
	return &DepGraph{
		nodes:   nodes,
		vars:    vars,
		readMks: readMks,
		exports: er.exports,
	}
}

func findKatiDir() {
	switch runtime.GOOS {
	case "linux":
		kati, err := os.Readlink("/proc/self/exe")
		if err != nil {
			panic(err)
		}
		katiDir = filepath.Dir(kati)
	default:
		panic(fmt.Sprintf("unknown OS: %s", runtime.GOOS))
	}
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	findKatiDir()
	parseFlags()
	if cpuprofile != "" {
		f, err := os.Create(cpuprofile)
		if err != nil {
			panic(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}
	defer maybeWriteHeapProfile()
	defer dumpStats()
	if memstats != "" {
		t := template.Must(template.New("memstats").Parse(memstats))
		var ms runtime.MemStats
		runtime.ReadMemStats(&ms)
		var buf bytes.Buffer
		err := t.Execute(&buf, ms)
		fmt.Println(buf.String())
		if err != nil {
			panic(err)
		}
		defer func() {
			var ms runtime.MemStats
			runtime.ReadMemStats(&ms)
			var buf bytes.Buffer
			t.Execute(&buf, ms)
			fmt.Println(buf.String())
		}()
	}

	clvars, targets := parseCommandLine()
	InitMakefileCache()

	g := getDepGraph(clvars, targets)
	nodes := g.nodes
	vars := g.vars

	if eagerCmdEvalFlag {
		startTime := time.Now()
		EvalCommands(nodes, vars)
		LogStats("eager eval command time: %q", time.Since(startTime))
	}

	if saveGOB != "" {
		startTime := time.Now()
		DumpDepGraph(g, saveGOB, targets)
		LogStats("serialize time: %q", time.Since(startTime))
	}
	if saveJSON != "" {
		startTime := time.Now()
		DumpDepGraphAsJSON(g, saveJSON, targets)
		LogStats("serialize time: %q", time.Since(startTime))
	}

	if useCache && !g.isCached {
		startTime := time.Now()
		DumpDepGraphCache(g, targets)
		LogStats("serialize time: %q", time.Since(startTime))
	}

	if generateNinja {
		startTime := time.Now()
		GenerateNinja(g)
		LogStats("generate ninja time: %q", time.Since(startTime))
		return
	}

	if syntaxCheckOnlyFlag {
		return
	}

	if queryFlag != "" {
		HandleQuery(queryFlag, g)
		return
	}

	// TODO: Handle target specific variables.
	ev := newEvaluator(vars)
	for name, export := range g.exports {
		if export {
			os.Setenv(name, ev.EvaluateVar(name))
		} else {
			os.Unsetenv(name)
		}
	}

	startTime := time.Now()
	ex := NewExecutor(vars)
	err := ex.Exec(nodes)
	if err != nil {
		panic(err)
	}
	LogStats("exec time: %q", time.Since(startTime))
}
