/* Copyright 2018 The Bazel Authors. 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.
*/

// Loads and runs registered analyses on a well-typed Go package.
// The code in this file is combined with the code generated by
// generate_nogo_main.go.

package main

import (
	"bytes"
	"encoding/gob"
	"errors"
	"flag"
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"go/types"
	"io/ioutil"
	"log"
	"os"
	"reflect"
	"regexp"
	"sort"
	"strings"
	"sync"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/internal/facts"
	"golang.org/x/tools/go/gcexportdata"
)

func init() {
	if err := analysis.Validate(analyzers); err != nil {
		log.Fatal(err)
	}
}

var typesSizes = types.SizesFor("gc", os.Getenv("GOARCH"))

func main() {
	log.SetFlags(0) // no timestamp
	log.SetPrefix("nogo: ")
	if err := run(os.Args[1:]); err != nil {
		log.Fatal(err)
	}
}

// run returns an error if there is a problem loading the package or if any
// analysis fails.
func run(args []string) error {
	args, _, err := expandParamsFiles(args)
	if err != nil {
		return fmt.Errorf("error reading paramfiles: %v", err)
	}

	factMap := factMultiFlag{}
	flags := flag.NewFlagSet("nogo", flag.ExitOnError)
	flags.Var(&factMap, "fact", "Import path and file containing facts for that library, separated by '=' (may be repeated)'")
	importcfg := flags.String("importcfg", "", "The import configuration file")
	packagePath := flags.String("p", "", "The package path (importmap) of the package being compiled")
	xPath := flags.String("x", "", "The archive file where serialized facts should be written")
	flags.Parse(args)
	srcs := flags.Args()

	packageFile, importMap, err := readImportCfg(*importcfg)
	if err != nil {
		return fmt.Errorf("error parsing importcfg: %v", err)
	}

	diagnostics, facts, err := checkPackage(analyzers, *packagePath, packageFile, importMap, factMap, srcs)
	if err != nil {
		return fmt.Errorf("error running analyzers: %v", err)
	}
	if diagnostics != "" {
		return fmt.Errorf("errors found by nogo during build-time code analysis:\n%s\n", diagnostics)
	}
	if *xPath != "" {
		if err := ioutil.WriteFile(abs(*xPath), facts, 0666); err != nil {
			return fmt.Errorf("error writing facts: %v", err)
		}
	}

	return nil
}

// Adapted from go/src/cmd/compile/internal/gc/main.go. Keep in sync.
func readImportCfg(file string) (packageFile map[string]string, importMap map[string]string, err error) {
	packageFile, importMap = make(map[string]string), make(map[string]string)
	data, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, nil, fmt.Errorf("-importcfg: %v", err)
	}

	for lineNum, line := range strings.Split(string(data), "\n") {
		lineNum++ // 1-based
		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}

		var verb, args string
		if i := strings.Index(line, " "); i < 0 {
			verb = line
		} else {
			verb, args = line[:i], strings.TrimSpace(line[i+1:])
		}
		var before, after string
		if i := strings.Index(args, "="); i >= 0 {
			before, after = args[:i], args[i+1:]
		}
		switch verb {
		default:
			return nil, nil, fmt.Errorf("%s:%d: unknown directive %q", file, lineNum, verb)
		case "importmap":
			if before == "" || after == "" {
				return nil, nil, fmt.Errorf(`%s:%d: invalid importmap: syntax is "importmap old=new"`, file, lineNum)
			}
			importMap[before] = after
		case "packagefile":
			if before == "" || after == "" {
				return nil, nil, fmt.Errorf(`%s:%d: invalid packagefile: syntax is "packagefile path=filename"`, file, lineNum)
			}
			packageFile[before] = after
		}
	}
	return packageFile, importMap, nil
}

// checkPackage runs all the given analyzers on the specified package and
// returns the source code diagnostics that the must be printed in the build log.
// It returns an empty string if no source code diagnostics need to be printed.
//
// This implementation was adapted from that of golang.org/x/tools/go/checker/internal/checker.
func checkPackage(analyzers []*analysis.Analyzer, packagePath string, packageFile, importMap map[string]string, factMap map[string]string, filenames []string) (string, []byte, error) {
	// Register fact types and establish dependencies between analyzers.
	actions := make(map[*analysis.Analyzer]*action)
	var visit func(a *analysis.Analyzer) *action
	visit = func(a *analysis.Analyzer) *action {
		act, ok := actions[a]
		if !ok {
			act = &action{a: a}
			actions[a] = act
			for _, f := range a.FactTypes {
				act.usesFacts = true
				gob.Register(f)
			}
			act.deps = make([]*action, len(a.Requires))
			for i, req := range a.Requires {
				dep := visit(req)
				if dep.usesFacts {
					act.usesFacts = true
				}
				act.deps[i] = dep
			}
		}
		return act
	}

	roots := make([]*action, 0, len(analyzers))
	for _, a := range analyzers {
		if cfg, ok := configs[a.Name]; ok {
			for flagKey, flagVal := range cfg.analyzerFlags {
				if strings.HasPrefix(flagKey, "-") {
					return "", nil, fmt.Errorf(
						"%s: flag should not begin with '-': %s", a.Name, flagKey)
				}
				if flag := a.Flags.Lookup(flagKey); flag == nil {
					return "", nil, fmt.Errorf("%s: unrecognized flag: %s", a.Name, flagKey)
				}
				if err := a.Flags.Set(flagKey, flagVal); err != nil {
					return "", nil, fmt.Errorf(
						"%s: invalid value for flag: %s=%s: %w", a.Name, flagKey, flagVal, err)
				}
			}
		}
		roots = append(roots, visit(a))
	}

	// Load the package, including AST, types, and facts.
	imp := newImporter(importMap, packageFile, factMap)
	pkg, err := load(packagePath, imp, filenames)
	if err != nil {
		return "", nil, fmt.Errorf("error loading package: %v", err)
	}
	for _, act := range actions {
		act.pkg = pkg
	}

	// Execute the analyzers.
	execAll(roots)

	// Process diagnostics and encode facts for importers of this package.
	diagnostics := checkAnalysisResults(roots, pkg)
	facts := pkg.facts.Encode()
	return diagnostics, facts, nil
}

// An action represents one unit of analysis work: the application of
// one analysis to one package. Actions form a DAG within a
// package (as different analyzers are applied, either in sequence or
// parallel).
type action struct {
	once        sync.Once
	a           *analysis.Analyzer
	pass        *analysis.Pass
	pkg         *goPackage
	deps        []*action
	inputs      map[*analysis.Analyzer]interface{}
	result      interface{}
	diagnostics []analysis.Diagnostic
	usesFacts   bool
	err         error
}

func (act *action) String() string {
	return fmt.Sprintf("%s@%s", act.a, act.pkg)
}

func execAll(actions []*action) {
	var wg sync.WaitGroup
	wg.Add(len(actions))
	for _, act := range actions {
		go func(act *action) {
			defer wg.Done()
			act.exec()
		}(act)
	}
	wg.Wait()
}

func (act *action) exec() { act.once.Do(act.execOnce) }

func (act *action) execOnce() {
	// Analyze dependencies.
	execAll(act.deps)

	// Report an error if any dependency failed.
	var failed []string
	for _, dep := range act.deps {
		if dep.err != nil {
			failed = append(failed, dep.String())
		}
	}
	if failed != nil {
		sort.Strings(failed)
		act.err = fmt.Errorf("failed prerequisites: %s", strings.Join(failed, ", "))
		return
	}

	// Plumb the output values of the dependencies
	// into the inputs of this action.
	inputs := make(map[*analysis.Analyzer]interface{})
	for _, dep := range act.deps {
		// Same package, different analysis (horizontal edge):
		// in-memory outputs of prerequisite analyzers
		// become inputs to this analysis pass.
		inputs[dep.a] = dep.result
	}

	// Run the analysis.
	factFilter := make(map[reflect.Type]bool)
	for _, f := range act.a.FactTypes {
		factFilter[reflect.TypeOf(f)] = true
	}
	pass := &analysis.Pass{
		Analyzer:          act.a,
		Fset:              act.pkg.fset,
		Files:             act.pkg.syntax,
		Pkg:               act.pkg.types,
		TypesInfo:         act.pkg.typesInfo,
		ResultOf:          inputs,
		Report:            func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
		ImportPackageFact: act.pkg.facts.ImportPackageFact,
		ExportPackageFact: act.pkg.facts.ExportPackageFact,
		ImportObjectFact:  act.pkg.facts.ImportObjectFact,
		ExportObjectFact:  act.pkg.facts.ExportObjectFact,
		AllPackageFacts:   func() []analysis.PackageFact { return act.pkg.facts.AllPackageFacts(factFilter) },
		AllObjectFacts:    func() []analysis.ObjectFact { return act.pkg.facts.AllObjectFacts(factFilter) },
		TypesSizes:        typesSizes,
	}
	act.pass = pass

	var err error
	if act.pkg.illTyped && !pass.Analyzer.RunDespiteErrors {
		err = fmt.Errorf("analysis skipped due to type-checking error: %v", act.pkg.typeCheckError)
	} else {
		act.result, err = pass.Analyzer.Run(pass)
		if err == nil {
			if got, want := reflect.TypeOf(act.result), pass.Analyzer.ResultType; got != want {
				err = fmt.Errorf(
					"internal error: on package %s, analyzer %s returned a result of type %v, but declared ResultType %v",
					pass.Pkg.Path(), pass.Analyzer, got, want)
			}
		}
	}
	act.err = err
}

// load parses and type checks the source code in each file in filenames.
// load also deserializes facts stored for imported packages.
func load(packagePath string, imp *importer, filenames []string) (*goPackage, error) {
	if len(filenames) == 0 {
		return nil, errors.New("no filenames")
	}
	var syntax []*ast.File
	for _, file := range filenames {
		s, err := parser.ParseFile(imp.fset, file, nil, parser.ParseComments)
		if err != nil {
			return nil, err
		}
		syntax = append(syntax, s)
	}
	pkg := &goPackage{fset: imp.fset, syntax: syntax}

	config := types.Config{Importer: imp}
	info := &types.Info{
		Types:      make(map[ast.Expr]types.TypeAndValue),
		Uses:       make(map[*ast.Ident]types.Object),
		Defs:       make(map[*ast.Ident]types.Object),
		Implicits:  make(map[ast.Node]types.Object),
		Scopes:     make(map[ast.Node]*types.Scope),
		Selections: make(map[*ast.SelectorExpr]*types.Selection),
	}

	initInstanceInfo(info)

	types, err := config.Check(packagePath, pkg.fset, syntax, info)
	if err != nil {
		pkg.illTyped, pkg.typeCheckError = true, err
	}
	pkg.types, pkg.typesInfo = types, info

	pkg.facts, err = facts.Decode(pkg.types, imp.readFacts)
	if err != nil {
		return nil, fmt.Errorf("internal error decoding facts: %v", err)
	}

	return pkg, nil
}

// A goPackage describes a loaded Go package.
type goPackage struct {
	// fset provides position information for types, typesInfo, and syntax.
	// It is set only when types is set.
	fset *token.FileSet
	// syntax is the package's syntax trees.
	syntax []*ast.File
	// types provides type information for the package.
	types *types.Package
	// facts contains information saved by the analysis framework. Passes may
	// import facts for imported packages and may also export facts for this
	// package to be consumed by analyses in downstream packages.
	facts *facts.Set
	// illTyped indicates whether the package or any dependency contains errors.
	// It is set only when types is set.
	illTyped bool
	// typeCheckError contains any error encountered during type-checking. It is
	// only set when illTyped is true.
	typeCheckError error
	// typesInfo provides type information about the package's syntax trees.
	// It is set only when syntax is set.
	typesInfo *types.Info
}

func (g *goPackage) String() string {
	return g.types.Path()
}

// checkAnalysisResults checks the analysis diagnostics in the given actions
// and returns a string containing all the diagnostics that should be printed
// to the build log.
func checkAnalysisResults(actions []*action, pkg *goPackage) string {
	type entry struct {
		analysis.Diagnostic
		*analysis.Analyzer
	}
	var diagnostics []entry
	var errs []error
	for _, act := range actions {
		if act.err != nil {
			// Analyzer failed.
			errs = append(errs, fmt.Errorf("analyzer %q failed: %v", act.a.Name, act.err))
			continue
		}
		if len(act.diagnostics) == 0 {
			continue
		}
		config, ok := configs[act.a.Name]
		if !ok {
			// If the analyzer is not explicitly configured, it emits diagnostics for
			// all files.
			for _, diag := range act.diagnostics {
				diagnostics = append(diagnostics, entry{Diagnostic: diag, Analyzer: act.a})
			}
			continue
		}
		// Discard diagnostics based on the analyzer configuration.
		for _, d := range act.diagnostics {
			// NOTE(golang.org/issue/31008): nilness does not set positions,
			// so don't assume the position is valid.
			p := pkg.fset.Position(d.Pos)
			filename := "-"
			if p.IsValid() {
				filename = p.Filename
			}
			include := true
			if len(config.onlyFiles) > 0 {
				// This analyzer emits diagnostics for only a set of files.
				include = false
				for _, pattern := range config.onlyFiles {
					if pattern.MatchString(filename) {
						include = true
						break
					}
				}
			}
			if include {
				for _, pattern := range config.excludeFiles {
					if pattern.MatchString(filename) {
						include = false
						break
					}
				}
			}
			if include {
				diagnostics = append(diagnostics, entry{Diagnostic: d, Analyzer: act.a})
			}
		}
	}
	if len(diagnostics) == 0 && len(errs) == 0 {
		return ""
	}

	sort.Slice(diagnostics, func(i, j int) bool {
		return diagnostics[i].Pos < diagnostics[j].Pos
	})
	errMsg := &bytes.Buffer{}
	sep := ""
	for _, err := range errs {
		errMsg.WriteString(sep)
		sep = "\n"
		errMsg.WriteString(err.Error())
	}
	for _, d := range diagnostics {
		errMsg.WriteString(sep)
		sep = "\n"
		fmt.Fprintf(errMsg, "%s: %s (%s)", pkg.fset.Position(d.Pos), d.Message, d.Name)
	}
	return errMsg.String()
}

// config determines which source files an analyzer will emit diagnostics for.
// config values are generated in another file that is compiled with
// nogo_main.go by the nogo rule.
type config struct {
	// onlyFiles is a list of regular expressions that match files an analyzer
	// will emit diagnostics for. When empty, the analyzer will emit diagnostics
	// for all files.
	onlyFiles []*regexp.Regexp

	// excludeFiles is a list of regular expressions that match files that an
	// analyzer will not emit diagnostics for.
	excludeFiles []*regexp.Regexp

	// analyzerFlags is a map of flag names to flag values which will be passed
	// to Analyzer.Flags. Note that no leading '-' should be present in a flag
	// name
	analyzerFlags map[string]string
}

// importer is an implementation of go/types.Importer that imports type
// information from the export data in compiled .a files.
type importer struct {
	fset         *token.FileSet
	importMap    map[string]string         // map import path in source code to package path
	packageCache map[string]*types.Package // cache of previously imported packages
	packageFile  map[string]string         // map package path to .a file with export data
	factMap      map[string]string         // map import path in source code to file containing serialized facts
}

func newImporter(importMap, packageFile map[string]string, factMap map[string]string) *importer {
	return &importer{
		fset:         token.NewFileSet(),
		importMap:    importMap,
		packageCache: make(map[string]*types.Package),
		packageFile:  packageFile,
		factMap:      factMap,
	}
}

func (i *importer) Import(path string) (*types.Package, error) {
	if imp, ok := i.importMap[path]; ok {
		// Translate import path if necessary.
		path = imp
	}
	if path == "unsafe" {
		// Special case: go/types has pre-defined type information for unsafe.
		// See https://github.com/golang/go/issues/13882.
		return types.Unsafe, nil
	}
	if pkg, ok := i.packageCache[path]; ok && pkg.Complete() {
		return pkg, nil // cache hit
	}

	archive, ok := i.packageFile[path]
	if !ok {
		return nil, fmt.Errorf("could not import %q", path)
	}
	// open file
	f, err := os.Open(archive)
	if err != nil {
		return nil, err
	}
	defer func() {
		f.Close()
		if err != nil {
			// add file name to error
			err = fmt.Errorf("reading export data: %s: %v", archive, err)
		}
	}()

	r, err := gcexportdata.NewReader(f)
	if err != nil {
		return nil, err
	}

	return gcexportdata.Read(r, i.fset, i.packageCache, path)
}

func (i *importer) readFacts(path string) ([]byte, error) {
	archive := i.factMap[path]
	if archive == "" {
		// Packages that were not built with the nogo toolchain will not be
		// analyzed, so there's no opportunity to store facts. This includes
		// packages in the standard library and packages built with go_tool_library,
		// such as coverdata. Analyzers are expected to hard code information
		// about standard library definitions and must gracefully handle packages
		// that don't have facts. For example, the "printf" analyzer must know
		// fmt.Printf accepts a format string.
		return nil, nil
	}
	factReader, err := readFileInArchive(nogoFact, archive)
	if os.IsNotExist(err) {
		// Packages that were not built with the nogo toolchain will not be
		// analyzed, so there's no opportunity to store facts. This includes
		// packages in the standard library and packages built with go_tool_library,
		// such as coverdata.
		return nil, nil
	} else if err != nil {
		return nil, err
	}
	defer factReader.Close()
	return ioutil.ReadAll(factReader)
}

type factMultiFlag map[string]string

func (m *factMultiFlag) String() string {
	if m == nil || len(*m) == 0 {
		return ""
	}
	return fmt.Sprintf("%v", *m)
}

func (m *factMultiFlag) Set(v string) error {
	parts := strings.Split(v, "=")
	if len(parts) != 2 {
		return fmt.Errorf("badly formatted -fact flag: %s", v)
	}
	(*m)[parts[0]] = parts[1]
	return nil
}
