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

package main

import (
	"fmt"
	"go/build"
	"go/doc"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"time"
)

// A Package describes a single package found in a directory.
type Package struct {
	// Note: These fields are part of the go command's public API.
	// See list.go.  It is okay to add fields, but not to change or
	// remove existing ones.  Keep in sync with list.go
	Name       string // package name
	Doc        string `json:",omitempty"` // package documentation string
	ImportPath string // import path of package in dir
	Dir        string // directory containing package sources
	Version    string `json:",omitempty"` // version of installed package (TODO)
	Standard   bool   `json:",omitempty"` // is this package part of the standard Go library?
	Stale      bool   `json:",omitempty"` // would 'go install' do anything for this package?

	// Source files
	GoFiles    []string // .go source files (excluding CgoFiles)
	CFiles     []string `json:",omitempty"` // .c source files
	HFiles     []string `json:",omitempty"` // .h source files
	SFiles     []string `json:",omitempty"` // .s source files
	CgoFiles   []string `json:",omitempty"` // .go sources files that import "C"
	CgoCFLAGS  []string `json:",omitempty"` // cgo: flags for C compiler
	CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker

	// Dependency information
	Imports []string `json:",omitempty"` // import paths used by this package
	Deps    []string `json:",omitempty"` // all (recursively) imported dependencies

	// Unexported fields are not part of the public API.
	t       *build.Tree
	pkgdir  string
	info    *build.DirInfo
	imports []*Package
	gofiles []string // GoFiles+CgoFiles, absolute paths
	target  string   // installed file for this package (may be executable)
}

// packageCache is a lookup cache for loadPackage,
// so that if we look up a package multiple times
// we return the same pointer each time.
var packageCache = map[string]*Package{}

// loadPackage scans directory named by arg,
// which is either an import path or a file system path
// (if the latter, must be rooted or begin with . or ..),
// and returns a *Package describing the package
// found in that directory.
func loadPackage(arg string) (*Package, error) {
	// Check package cache.
	if p := packageCache[arg]; p != nil {
		// We use p.imports==nil to detect a package that
		// is in the midst of its own loadPackage call
		// (all the recursion below happens before p.imports gets set).
		if p.imports == nil {
			return nil, fmt.Errorf("import loop at %s", arg)
		}
		return p, nil
	}

	// Find basic information about package path.
	t, importPath, err := build.FindTree(arg)
	dir := ""
	// Maybe it is a standard command.
	if err != nil && !filepath.IsAbs(arg) && strings.HasPrefix(arg, "cmd/") {
		goroot := build.Path[0]
		p := filepath.Join(goroot.Path, "src", arg)
		if st, err1 := os.Stat(p); err1 == nil && st.IsDir() {
			t = goroot
			importPath = arg
			dir = p
			err = nil
		}
	}
	if err != nil {
		return nil, err
	}

	if dir == "" {
		dir = filepath.Join(t.SrcDir(), filepath.FromSlash(importPath))
	}

	// Maybe we know the package by its directory.
	if p := packageCache[dir]; p != nil {
		if p.imports == nil {
			return nil, fmt.Errorf("import loop at %s", arg)
		}
		return p, nil
	}

	return scanPackage(&build.DefaultContext, t, arg, importPath, dir)
}

func scanPackage(ctxt *build.Context, t *build.Tree, arg, importPath, dir string) (*Package, error) {
	// Read the files in the directory to learn the structure
	// of the package.
	info, err := ctxt.ScanDir(dir)
	if err != nil {
		return nil, err
	}

	var target string
	if info.Package == "main" {
		_, elem := filepath.Split(importPath)
		target = filepath.Join(t.BinDir(), elem)
		if ctxt.GOOS == "windows" {
			target += ".exe"
		}
	} else {
		target = filepath.Join(t.PkgDir(), filepath.FromSlash(importPath)+".a")
	}

	p := &Package{
		Name:       info.Package,
		Doc:        doc.CommentText(info.PackageComment),
		ImportPath: importPath,
		Dir:        dir,
		Imports:    info.Imports,
		GoFiles:    info.GoFiles,
		CFiles:     info.CFiles,
		HFiles:     info.HFiles,
		SFiles:     info.SFiles,
		CgoFiles:   info.CgoFiles,
		CgoCFLAGS:  info.CgoCFLAGS,
		CgoLDFLAGS: info.CgoLDFLAGS,
		Standard:   t.Goroot && !strings.Contains(importPath, "."),
		target:     target,
		t:          t,
		info:       info,
	}

	var built time.Time
	if fi, err := os.Stat(target); err == nil {
		built = fi.ModTime()
	}

	// Build list of full paths to all Go files in the package,
	// for use by commands like go fmt.
	for _, f := range info.GoFiles {
		p.gofiles = append(p.gofiles, filepath.Join(dir, f))
	}
	for _, f := range info.CgoFiles {
		p.gofiles = append(p.gofiles, filepath.Join(dir, f))
	}
	sort.Strings(p.gofiles)
	srcss := [][]string{
		p.GoFiles,
		p.CFiles,
		p.HFiles,
		p.SFiles,
		p.CgoFiles,
	}
Stale:
	for _, srcs := range srcss {
		for _, src := range srcs {
			if fi, err := os.Stat(filepath.Join(p.Dir, src)); err != nil || fi.ModTime().After(built) {
				//println("STALE", p.ImportPath, "needs", src, err)
				p.Stale = true
				break Stale
			}
		}
	}

	importPaths := p.Imports
	// Packages that use cgo import runtime/cgo implicitly,
	// except runtime/cgo itself.
	if len(info.CgoFiles) > 0 && (!p.Standard || p.ImportPath != "runtime/cgo") {
		importPaths = append(importPaths, "runtime/cgo")
	}
	// Everything depends on runtime, except runtime and unsafe.
	if !p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "unsafe") {
		importPaths = append(importPaths, "runtime")
	}

	// Record package under both import path and full directory name.
	packageCache[dir] = p
	packageCache[importPath] = p

	// Build list of imported packages and full dependency list.
	imports := make([]*Package, 0, len(p.Imports))
	deps := make(map[string]bool)
	for _, path := range importPaths {
		deps[path] = true
		if path == "C" {
			continue
		}
		p1, err := loadPackage(path)
		if err != nil {
			delete(packageCache, dir)
			delete(packageCache, importPath)
			// Add extra error detail to show full import chain.
			// Always useful, but especially useful in import loops.
			return nil, fmt.Errorf("%s: import %s\n\t%v", arg, path, err)
		}
		imports = append(imports, p1)
		for _, dep := range p1.Deps {
			deps[dep] = true
		}
		if p1.Stale {
			p.Stale = true
		}
		// p1.target can be empty only if p1 is not a real package,
		// such as package unsafe or the temporary packages
		// created during go test.
		if !p.Stale && p1.target != "" {
			if fi, err := os.Stat(p1.target); err != nil || fi.ModTime().After(built) {
				//println("STALE", p.ImportPath, "needs", p1.target, err)
				//println("BUILT", built.String(), "VS", fi.ModTime().String())
				p.Stale = true
			}
		}
	}
	p.imports = imports

	p.Deps = make([]string, 0, len(deps))
	for dep := range deps {
		p.Deps = append(p.Deps, dep)
	}
	sort.Strings(p.Deps)

	// unsafe is a fake package and is never out-of-date.
	if p.Standard && p.ImportPath == "unsafe" {
		p.Stale = false
		p.target = ""
	}

	return p, nil
}

// packages returns the packages named by the
// command line arguments 'args'.
func packages(args []string) []*Package {
	args = importPaths(args)
	var pkgs []*Package
	for _, arg := range args {
		pkg, err := loadPackage(arg)
		if err != nil {
			errorf("%s", err)
			continue
		}
		pkgs = append(pkgs, pkg)
	}
	return pkgs
}
