// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Generates a depfile for a Go package that can be consumed by Ninja.
package main

import (
	"errors"
	"flag"
	"fmt"
	"go/build"
	"log"
	"os"
	"runtime"
	"sort"
	"strings"
	"sync"
)

type stringsFlag []string

func (v *stringsFlag) String() string { return strings.Join(*v, " ") }

func (v *stringsFlag) Set(s string) error {
	*v = strings.Split(s, " ")
	if *v == nil {
		*v = []string{}
	}
	return nil
}

type mapFlag map[string]string

func (v *mapFlag) String() string {
	var s []string
	for from, to := range *v {
		s = append(s, fmt.Sprintf("%s=%s", from, to))
	}
	return strings.Join(s, " ")
}

func (v *mapFlag) Set(s string) error {
	if strings.Count(s, "=") != 1 {
		return errors.New("argument must be of the form from=to")
	}
	i := strings.Index(s, "=")
	from, to := s[:i], s[i+1:]
	if from == "" || to == "" {
		return errors.New("from and to must be non-empty")
	}
	(*v)[from] = to
	return nil
}

var (
	ctx       = build.Default
	output    string
	test      bool
	prefixmap = mapFlag{}
)

func init() {
	flag.Var((*stringsFlag)(&ctx.BuildTags), "tags", "build tags")
	flag.StringVar(&output, "o", "", "name of the resulting executable")
	flag.BoolVar(&test, "test", false, "whether this is a test target")
	flag.Var(&prefixmap, "prefixmap", "path prefix mapping in the from=to format")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: godepfile [packages]\n")
		flag.PrintDefaults()
	}
}

func appendAndPrefix(slice []string, prefix string, src []string) []string {
	for _, s := range src {
		slice = append(slice, prefix+s)
	}
	return slice
}

func main() {
	flag.Parse()

	if len(flag.Args()) == 0 {
		flag.Usage()
		os.Exit(1)
	}

	var mu sync.Mutex
	deps := make(map[string]bool)
	paths := make(map[string]bool)

	fdlimit := make(chan struct{}, 128)
	var wg sync.WaitGroup
	var scan func(path, srcDir string, test bool)
	scan = func(path, srcDir string, test bool) {
		defer wg.Done()

		mu.Lock()
		_, done := paths[path]
		if !done {
			paths[path] = true
		}
		mu.Unlock()

		if done {
			return
		}

		if path == "C" {
			return
		}

		fdlimit <- struct{}{}
		defer func() { <-fdlimit }()

		pkg, err := ctx.Import(path, srcDir, 0)
		if err != nil {
			log.Fatalf("%s: %v", path, err)
		}

		var files []string
		srcdir := pkg.Dir + "/"
		for from, to := range prefixmap {
			if strings.HasPrefix(srcdir, from) {
				srcdir = to + srcdir[len(from):]
			}
		}

		files = appendAndPrefix(files, srcdir, pkg.GoFiles)
		files = appendAndPrefix(files, srcdir, pkg.CgoFiles)
		files = appendAndPrefix(files, srcdir, pkg.CFiles)
		files = appendAndPrefix(files, srcdir, pkg.CXXFiles)
		files = appendAndPrefix(files, srcdir, pkg.HFiles)
		files = appendAndPrefix(files, srcdir, pkg.SFiles)
		files = appendAndPrefix(files, srcdir, pkg.SwigFiles)
		files = appendAndPrefix(files, srcdir, pkg.SwigCXXFiles)

		if test {
			files = appendAndPrefix(files, srcdir, pkg.TestGoFiles)
			files = appendAndPrefix(files, srcdir, pkg.XTestGoFiles)
		}

		mu.Lock()
		for _, file := range files {
			deps[file] = true
		}
		mu.Unlock()

		if pkg.Name == "main" && output == "" {
			bindir := os.Getenv("GOBIN")
			if bindir == "" {
				bindir = pkg.BinDir
			}
			if ctx.GOOS == runtime.GOOS && ctx.GOARCH == runtime.GOARCH {
				output = ctx.JoinPath(bindir, path)
			} else {
				output = ctx.JoinPath(bindir, ctx.GOOS+"_"+ctx.GOARCH, path)
			}
		}

		for _, imp := range pkg.Imports {
			wg.Add(1)
			go scan(imp, pkg.Dir, false)
		}

		if test {
			for _, imp := range pkg.TestImports {
				wg.Add(1)
				go scan(imp, pkg.Dir, false)
			}
			for _, imp := range pkg.XTestImports {
				wg.Add(1)
				go scan(imp, pkg.Dir, false)
			}
		}
	}

	for _, root := range flag.Args() {
		wg.Add(1)
		go scan(root, "", test)
	}
	wg.Wait()

	fmt.Printf("%s:", output)
	var depnames []string
	for path := range deps {
		depnames = append(depnames, path)
	}
	sort.Strings(depnames)
	for path := range deps {
		fmt.Printf(" %s", path)
	}
	fmt.Printf("\n")
}
