// Copyright 2015 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.

// +build go1.5

// The bundle command concatenates the source files of a package,
// renaming package-level names by adding a prefix and renaming
// identifiers as needed to preserve referential integrity.
//
// Example:
// 	$ bundle golang.org/x/net/http2 net/http http2
//
// The command above prints a single file containing the code of
// golang.org/x/net/http2, suitable for inclusion in package net/http,
// in which toplevel names have been prefixed with "http2".
//
// Assumptions:
// - no file in the package imports "C", that is, uses cgo.
// - no file in the package has GOOS or GOARCH build tags or file names.
// - comments associated with the package or import declarations,
//   may be discarded, as may comments associated with no top-level
//   declaration at all.
// - neither the original package nor the destination package contains
//   any identifiers starting with the designated prefix.
//   (This allows us to avoid various conflict checks.)
// - there are no renaming imports.
// - test files are ignored.
// - none of the renamed identifiers is significant
//   to reflection-based logic.
//
// Only package-level var, func, const, and type objects are renamed,
// and embedded fields of renamed types.  No methods are renamed, so we
// needn't worry about preserving interface satisfaction.
//
package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/build"
	"go/format"
	"go/parser"
	"go/token"
	"go/types"
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/tools/go/loader"
)

func main() {
	log.SetPrefix("bundle: ")
	log.SetFlags(0)

	flag.Parse()
	args := flag.Args()
	if len(args) != 3 {
		log.Fatal(`Usage: bundle package dest prefix

Arguments:
 package is the import path of the package to concatenate.
 dest is the import path of the package in which the resulting file will reside.
 prefix is the string to attach to all renamed identifiers.
`)
	}
	initialPkg, dest, prefix := args[0], args[1], args[2]

	if err := bundle(os.Stdout, initialPkg, dest, prefix); err != nil {
		log.Fatal(err)
	}
}

var ctxt = &build.Default

func bundle(w io.Writer, initialPkg, dest, prefix string) error {
	// Load the initial package.
	conf := loader.Config{ParserMode: parser.ParseComments, Build: ctxt}
	conf.TypeCheckFuncBodies = func(p string) bool { return p == initialPkg }
	conf.Import(initialPkg)

	lprog, err := conf.Load()
	if err != nil {
		log.Fatal(err)
	}

	info := lprog.Package(initialPkg)

	objsToUpdate := make(map[types.Object]bool)
	var rename func(from types.Object)
	rename = func(from types.Object) {
		if !objsToUpdate[from] {
			objsToUpdate[from] = true

			// Renaming a type that is used as an embedded field
			// requires renaming the field too. e.g.
			// 	type T int // if we rename this to U..
			// 	var s struct {T}
			// 	print(s.T) // ...this must change too
			if _, ok := from.(*types.TypeName); ok {
				for id, obj := range info.Uses {
					if obj == from {
						if field := info.Defs[id]; field != nil {
							rename(field)
						}
					}
				}
			}
		}
	}

	// Rename each package-level object.
	scope := info.Pkg.Scope()
	for _, name := range scope.Names() {
		rename(scope.Lookup(name))
	}

	var out bytes.Buffer

	fmt.Fprintf(&out, "// Code generated by golang.org/x/tools/cmd/bundle command:\n")
	fmt.Fprintf(&out, "//   $ bundle %s %s %s\n\n", initialPkg, dest, prefix)

	// Concatenate package comments from all files...
	for _, f := range info.Files {
		if doc := f.Doc.Text(); strings.TrimSpace(doc) != "" {
			for _, line := range strings.Split(doc, "\n") {
				fmt.Fprintf(&out, "// %s\n", line)
			}
		}
	}
	// ...but don't let them become the actual package comment.
	fmt.Fprintln(&out)

	// TODO(adonovan): don't assume pkg.name == basename(pkg.path).
	fmt.Fprintf(&out, "package %s\n\n", filepath.Base(dest))

	// Print a single declaration that imports all necessary packages.
	// TODO(adonovan):
	// - support renaming imports.
	// - preserve comments from the original import declarations.
	for _, f := range info.Files {
		for _, imp := range f.Imports {
			if imp.Name != nil {
				log.Fatalf("%s: renaming imports not supported",
					lprog.Fset.Position(imp.Pos()))
			}
		}
	}
	fmt.Fprintln(&out, "import (")
	for _, p := range info.Pkg.Imports() {
		if p.Path() == dest {
			continue
		}
		fmt.Fprintf(&out, "\t%q\n", p.Path())
	}
	fmt.Fprintln(&out, ")\n")

	// Modify and print each file.
	for _, f := range info.Files {
		// Update renamed identifiers.
		for id, obj := range info.Defs {
			if objsToUpdate[obj] {
				id.Name = prefix + obj.Name()
			}
		}
		for id, obj := range info.Uses {
			if objsToUpdate[obj] {
				id.Name = prefix + obj.Name()
			}
		}

		// For each qualified identifier that refers to the
		// destination package, remove the qualifier.
		// The "@@@." strings are removed in postprocessing.
		ast.Inspect(f, func(n ast.Node) bool {
			if sel, ok := n.(*ast.SelectorExpr); ok {
				if id, ok := sel.X.(*ast.Ident); ok {
					if obj, ok := info.Uses[id].(*types.PkgName); ok {
						if obj.Imported().Path() == dest {
							id.Name = "@@@"
						}
					}
				}
			}
			return true
		})

		// Pretty-print package-level declarations.
		// but no package or import declarations.
		//
		// TODO(adonovan): this may cause loss of comments
		// preceding or associated with the package or import
		// declarations or not associated with any declaration.
		// Check.
		var buf bytes.Buffer
		for _, decl := range f.Decls {
			if decl, ok := decl.(*ast.GenDecl); ok && decl.Tok == token.IMPORT {
				continue
			}
			buf.Reset()
			format.Node(&buf, lprog.Fset, decl)
			// Remove each "@@@." in the output.
			// TODO(adonovan): not hygienic.
			out.Write(bytes.Replace(buf.Bytes(), []byte("@@@."), nil, -1))
			out.WriteString("\n\n")
		}
	}

	// Now format the entire thing.
	result, err := format.Source(out.Bytes())
	if err != nil {
		log.Fatalf("formatting failed: %v", err)
	}

	_, err = w.Write(result)
	return err
}
