// Copyright 2014 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 (
	"errors"
	"flag"
	"fmt"
	"go/build"
	"go/types"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

var (
	source  = flag.String("s", "", "only consider packages from src, where src is one of the supported compilers")
	verbose = flag.Bool("v", false, "verbose mode")
)

// lists of registered sources and corresponding importers
var (
	sources         []string
	importers       []types.Importer
	errImportFailed = errors.New("import failed")
)

func usage() {
	fmt.Fprintln(os.Stderr, "usage: godex [flags] {path|qualifiedIdent}")
	flag.PrintDefaults()
	os.Exit(2)
}

func report(msg string) {
	fmt.Fprintln(os.Stderr, "error: "+msg)
	os.Exit(2)
}

func main() {
	flag.Usage = usage
	flag.Parse()

	if flag.NArg() == 0 {
		report("no package name, path, or file provided")
	}

	var imp types.Importer = new(tryImporters)
	if *source != "" {
		imp = lookup(*source)
		if imp == nil {
			report("source (-s argument) must be one of: " + strings.Join(sources, ", "))
		}
	}

	for _, arg := range flag.Args() {
		path, name := splitPathIdent(arg)
		logf("\tprocessing %q: path = %q, name = %s\n", arg, path, name)

		// generate possible package path prefixes
		// (at the moment we do this for each argument - should probably cache the generated prefixes)
		prefixes := make(chan string)
		go genPrefixes(prefixes, !filepath.IsAbs(path) && !build.IsLocalImport(path))

		// import package
		pkg, err := tryPrefixes(prefixes, path, imp)
		if err != nil {
			logf("\t=> ignoring %q: %s\n", path, err)
			continue
		}

		// filter objects if needed
		var filter func(types.Object) bool
		if name != "" {
			filter = func(obj types.Object) bool {
				// TODO(gri) perhaps use regular expression matching here?
				return obj.Name() == name
			}
		}

		// print contents
		print(os.Stdout, pkg, filter)
	}
}

func logf(format string, args ...interface{}) {
	if *verbose {
		fmt.Fprintf(os.Stderr, format, args...)
	}
}

// splitPathIdent splits a path.name argument into its components.
// All but the last path element may contain dots.
func splitPathIdent(arg string) (path, name string) {
	if i := strings.LastIndex(arg, "."); i >= 0 {
		if j := strings.LastIndex(arg, "/"); j < i {
			// '.' is not part of path
			path = arg[:i]
			name = arg[i+1:]
			return
		}
	}
	path = arg
	return
}

// tryPrefixes tries to import the package given by (the possibly partial) path using the given importer imp
// by prepending all possible prefixes to path. It returns with the first package that it could import, or
// with an error.
func tryPrefixes(prefixes chan string, path string, imp types.Importer) (pkg *types.Package, err error) {
	for prefix := range prefixes {
		actual := path
		if prefix == "" {
			// don't use filepath.Join as it will sanitize the path and remove
			// a leading dot and then the path is not recognized as a relative
			// package path by the importers anymore
			logf("\ttrying no prefix\n")
		} else {
			actual = filepath.Join(prefix, path)
			logf("\ttrying prefix %q\n", prefix)
		}
		pkg, err = imp.Import(actual)
		if err == nil {
			break
		}
		logf("\t=> importing %q failed: %s\n", actual, err)
	}
	return
}

// tryImporters is an importer that tries all registered importers
// successively until one of them succeeds or all of them failed.
type tryImporters struct{}

func (t *tryImporters) Import(path string) (pkg *types.Package, err error) {
	for i, imp := range importers {
		logf("\t\ttrying %s import\n", sources[i])
		pkg, err = imp.Import(path)
		if err == nil {
			break
		}
		logf("\t\t=> %s import failed: %s\n", sources[i], err)
	}
	return
}

type protector struct {
	imp types.Importer
}

func (p *protector) Import(path string) (pkg *types.Package, err error) {
	defer func() {
		if recover() != nil {
			pkg = nil
			err = errImportFailed
		}
	}()
	return p.imp.Import(path)
}

// protect protects an importer imp from panics and returns the protected importer.
func protect(imp types.Importer) types.Importer {
	return &protector{imp}
}

// register registers an importer imp for a given source src.
func register(src string, imp types.Importer) {
	if lookup(src) != nil {
		panic(src + " importer already registered")
	}
	sources = append(sources, src)
	importers = append(importers, protect(imp))
}

// lookup returns the importer imp for a given source src.
func lookup(src string) types.Importer {
	for i, s := range sources {
		if s == src {
			return importers[i]
		}
	}
	return nil
}

func genPrefixes(out chan string, all bool) {
	out <- ""
	if all {
		platform := build.Default.GOOS + "_" + build.Default.GOARCH
		dirnames := append([]string{build.Default.GOROOT}, filepath.SplitList(build.Default.GOPATH)...)
		for _, dirname := range dirnames {
			walkDir(filepath.Join(dirname, "pkg", platform), "", out)
		}
	}
	close(out)
}

func walkDir(dirname, prefix string, out chan string) {
	fiList, err := ioutil.ReadDir(dirname)
	if err != nil {
		return
	}
	for _, fi := range fiList {
		if fi.IsDir() && !strings.HasPrefix(fi.Name(), ".") {
			prefix := filepath.Join(prefix, fi.Name())
			out <- prefix
			walkDir(filepath.Join(dirname, fi.Name()), prefix, out)
		}
	}
}
