// 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)
	scan = func(path, srcDir string) {
		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)
		}

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

	for _, root := range flag.Args() {
		wg.Add(1)
		go scan(root, "")
	}
	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")
}
