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

// Except for this comment and the import path, this file is a verbatim copy of the file
// with the same name in $GOROOT/src/go/internal/gccgoimporter.

// Package gccgoimporter implements Import for gccgo-generated object files.
package gccgoimporter // import "golang.org/x/tools/go/internal/gccgoimporter"

import (
	"debug/elf"
	"fmt"
	"go/types"
	"io"
	"os"
	"path/filepath"
	"strings"
)

// A PackageInit describes an imported package that needs initialization.
type PackageInit struct {
	Name     string // short package name
	InitFunc string // name of init function
	Priority int    // priority of init function, see InitData.Priority
}

// The gccgo-specific init data for a package.
type InitData struct {
	// Initialization priority of this package relative to other packages.
	// This is based on the maximum depth of the package's dependency graph;
	// it is guaranteed to be greater than that of its dependencies.
	Priority int

	// The list of packages which this package depends on to be initialized,
	// including itself if needed. This is the subset of the transitive closure of
	// the package's dependencies that need initialization.
	Inits []PackageInit
}

// Locate the file from which to read export data.
// This is intended to replicate the logic in gofrontend.
func findExportFile(searchpaths []string, pkgpath string) (string, error) {
	for _, spath := range searchpaths {
		pkgfullpath := filepath.Join(spath, pkgpath)
		pkgdir, name := filepath.Split(pkgfullpath)

		for _, filepath := range [...]string{
			pkgfullpath,
			pkgfullpath + ".gox",
			pkgdir + "lib" + name + ".so",
			pkgdir + "lib" + name + ".a",
			pkgfullpath + ".o",
		} {
			fi, err := os.Stat(filepath)
			if err == nil && !fi.IsDir() {
				return filepath, nil
			}
		}
	}

	return "", fmt.Errorf("%s: could not find export data (tried %s)", pkgpath, strings.Join(searchpaths, ":"))
}

const (
	gccgov1Magic    = "v1;\n"
	gccgov2Magic    = "v2;\n"
	goimporterMagic = "\n$$ "
	archiveMagic    = "!<ar"
)

// Opens the export data file at the given path. If this is an ELF file,
// searches for and opens the .go_export section. If this is an archive,
// reads the export data from the first member, which is assumed to be an ELF file.
// This is intended to replicate the logic in gofrontend.
func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err error) {
	f, err := os.Open(fpath)
	if err != nil {
		return
	}
	closer = f
	defer func() {
		if err != nil && closer != nil {
			f.Close()
		}
	}()

	var magic [4]byte
	_, err = f.ReadAt(magic[:], 0)
	if err != nil {
		return
	}

	var elfreader io.ReaderAt
	switch string(magic[:]) {
	case gccgov1Magic, gccgov2Magic, goimporterMagic:
		// Raw export data.
		reader = f
		return

	case archiveMagic:
		reader, err = arExportData(f)
		return

	default:
		elfreader = f
	}

	ef, err := elf.NewFile(elfreader)
	if err != nil {
		return
	}

	sec := ef.Section(".go_export")
	if sec == nil {
		err = fmt.Errorf("%s: .go_export section not found", fpath)
		return
	}

	reader = sec.Open()
	return
}

// An Importer resolves import paths to Packages. The imports map records
// packages already known, indexed by package path.
// An importer must determine the canonical package path and check imports
// to see if it is already present in the map. If so, the Importer can return
// the map entry. Otherwise, the importer must load the package data for the
// given path into a new *Package, record it in imports map, and return the
// package.
type Importer func(imports map[string]*types.Package, path, srcDir string, lookup func(string) (io.ReadCloser, error)) (*types.Package, error)

func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Importer {
	return func(imports map[string]*types.Package, pkgpath, srcDir string, lookup func(string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
		// TODO(gri): Use srcDir.
		// Or not. It's possible that srcDir will fade in importance as
		// the go command and other tools provide a translation table
		// for relative imports (like ./foo or vendored imports).
		if pkgpath == "unsafe" {
			return types.Unsafe, nil
		}

		var reader io.ReadSeeker
		var fpath string
		var rc io.ReadCloser
		if lookup != nil {
			if p := imports[pkgpath]; p != nil && p.Complete() {
				return p, nil
			}
			rc, err = lookup(pkgpath)
			if err != nil {
				return nil, err
			}
		}
		if rc != nil {
			defer rc.Close()
			rs, ok := rc.(io.ReadSeeker)
			if !ok {
				return nil, fmt.Errorf("gccgo importer requires lookup to return an io.ReadSeeker, have %T", rc)
			}
			reader = rs
			fpath = "<lookup " + pkgpath + ">"
			// Take name from Name method (like on os.File) if present.
			if n, ok := rc.(interface{ Name() string }); ok {
				fpath = n.Name()
			}
		} else {
			fpath, err = findExportFile(searchpaths, pkgpath)
			if err != nil {
				return nil, err
			}

			r, closer, err := openExportFile(fpath)
			if err != nil {
				return nil, err
			}
			if closer != nil {
				defer closer.Close()
			}
			reader = r
		}

		var magics string
		magics, err = readMagic(reader)
		if err != nil {
			return
		}

		if magics == archiveMagic {
			reader, err = arExportData(reader)
			if err != nil {
				return
			}
			magics, err = readMagic(reader)
			if err != nil {
				return
			}
		}

		switch magics {
		case gccgov1Magic, gccgov2Magic:
			var p parser
			p.init(fpath, reader, imports)
			pkg = p.parsePackage()
			if initmap != nil {
				initmap[pkg] = p.initdata
			}

		// Excluded for now: Standard gccgo doesn't support this import format currently.
		// case goimporterMagic:
		// 	var data []byte
		// 	data, err = ioutil.ReadAll(reader)
		// 	if err != nil {
		// 		return
		// 	}
		// 	var n int
		// 	n, pkg, err = importer.ImportData(imports, data)
		// 	if err != nil {
		// 		return
		// 	}

		// 	if initmap != nil {
		// 		suffixreader := bytes.NewReader(data[n:])
		// 		var p parser
		// 		p.init(fpath, suffixreader, nil)
		// 		p.parseInitData()
		// 		initmap[pkg] = p.initdata
		// 	}

		default:
			err = fmt.Errorf("unrecognized magic string: %q", magics)
		}

		return
	}
}

// readMagic reads the four bytes at the start of a ReadSeeker and
// returns them as a string.
func readMagic(reader io.ReadSeeker) (string, error) {
	var magic [4]byte
	if _, err := reader.Read(magic[:]); err != nil {
		return "", err
	}
	if _, err := reader.Seek(0, io.SeekStart); err != nil {
		return "", err
	}
	return string(magic[:]), nil
}
