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

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

import (
	"bytes"
	"debug/elf"
	"debug/xcoff"
	"fmt"
	"go/types"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"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"
	aixbigafMagic   = "<big"
)

// Opens the export data file at the given path. If this is an object 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 object 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 objreader io.ReaderAt
	switch string(magic[:]) {
	case gccgov1Magic, gccgov2Magic, goimporterMagic:
		// Raw export data.
		reader = f
		return

	case archiveMagic, aixbigafMagic:
		// TODO(pcc): Read the archive directly instead of using "ar".
		f.Close()
		closer = nil
		var cmd *exec.Cmd

		if runtime.GOOS == "aix" && runtime.GOARCH == "ppc64" {
			// AIX puts both 32-bit and 64-bit objects in the same archive.
			// Tell the AIX "ar" command to only care about 64-bit objects.
			cmd = exec.Command("ar", "-X64", "p", fpath)
		} else {
			cmd = exec.Command("ar", "p", fpath)
		}
		var out []byte
		out, err = cmd.Output()
		if err != nil {
			return
		}

		objreader = bytes.NewReader(out)

	default:
		objreader = f
	}

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

	xf, err := xcoff.NewFile(objreader)
	if err == nil {
		sdat := xf.CSect(".go_export")
		if sdat == nil {
			err = fmt.Errorf("%s: .go_export section not found", fpath)
			return
		}
		reader = bytes.NewReader(sdat)
		return
	}

	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
		if lookup != nil {
			if p := imports[pkgpath]; p != nil && p.Complete() {
				return p, nil
			}
			rc, err := lookup(pkgpath)
			if err == 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()
				}
			}
		}
		if reader == nil {
			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 magic [4]byte
		_, err = reader.Read(magic[:])
		if err != nil {
			return
		}
		_, err = reader.Seek(0, io.SeekStart)
		if err != nil {
			return
		}

		switch string(magic[:]) {
		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", string(magic[:]))
		}

		return
	}
}
