// 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 prefixmapFlag []struct{from, to string}

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

func (v *prefixmapFlag) 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 = append(*v, struct{from, to string}{from, to})
	return nil
}

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

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 _, p := range prefixmap {
			if strings.HasPrefix(srcdir, p.from) {
				srcdir = p.to + srcdir[len(p.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")
}
