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

// This file implements NewPackage.

package ast

import (
	"fmt"
	"go/scanner"
	"go/token"
	"strconv"
)

type pkgBuilder struct {
	fset   *token.FileSet
	errors scanner.ErrorList
}

func (p *pkgBuilder) error(pos token.Pos, msg string) {
	p.errors.Add(p.fset.Position(pos), msg)
}

func (p *pkgBuilder) errorf(pos token.Pos, format string, args ...interface{}) {
	p.error(pos, fmt.Sprintf(format, args...))
}

func (p *pkgBuilder) declare(scope, altScope *Scope, obj *Object) {
	alt := scope.Insert(obj)
	if alt == nil && altScope != nil {
		// see if there is a conflicting declaration in altScope
		alt = altScope.Lookup(obj.Name)
	}
	if alt != nil {
		prevDecl := ""
		if pos := alt.Pos(); pos.IsValid() {
			prevDecl = fmt.Sprintf("\n\tprevious declaration at %s", p.fset.Position(pos))
		}
		p.error(obj.Pos(), fmt.Sprintf("%s redeclared in this block%s", obj.Name, prevDecl))
	}
}

func resolve(scope *Scope, ident *Ident) bool {
	for ; scope != nil; scope = scope.Outer {
		if obj := scope.Lookup(ident.Name); obj != nil {
			ident.Obj = obj
			return true
		}
	}
	return false
}

// An Importer resolves import paths to package Objects.
// The imports map records the packages already imported,
// indexed by package id (canonical import path).
// An Importer must determine the canonical import path and
// check the map to see if it is already present in the imports map.
// If so, the Importer can return the map entry.  Otherwise, the
// Importer should load the package data for the given path into
// a new *Object (pkg), record pkg in the imports map, and then
// return pkg.
type Importer func(imports map[string]*Object, path string) (pkg *Object, err error)

// NewPackage creates a new Package node from a set of File nodes. It resolves
// unresolved identifiers across files and updates each file's Unresolved list
// accordingly. If a non-nil importer and universe scope are provided, they are
// used to resolve identifiers not declared in any of the package files. Any
// remaining unresolved identifiers are reported as undeclared. If the files
// belong to different packages, one package name is selected and files with
// different package names are reported and then ignored.
// The result is a package node and a scanner.ErrorList if there were errors.
//
func NewPackage(fset *token.FileSet, files map[string]*File, importer Importer, universe *Scope) (*Package, error) {
	var p pkgBuilder
	p.fset = fset

	// complete package scope
	pkgName := ""
	pkgScope := NewScope(universe)
	for _, file := range files {
		// package names must match
		switch name := file.Name.Name; {
		case pkgName == "":
			pkgName = name
		case name != pkgName:
			p.errorf(file.Package, "package %s; expected %s", name, pkgName)
			continue // ignore this file
		}

		// collect top-level file objects in package scope
		for _, obj := range file.Scope.Objects {
			p.declare(pkgScope, nil, obj)
		}
	}

	// package global mapping of imported package ids to package objects
	imports := make(map[string]*Object)

	// complete file scopes with imports and resolve identifiers
	for _, file := range files {
		// ignore file if it belongs to a different package
		// (error has already been reported)
		if file.Name.Name != pkgName {
			continue
		}

		// build file scope by processing all imports
		importErrors := false
		fileScope := NewScope(pkgScope)
		for _, spec := range file.Imports {
			if importer == nil {
				importErrors = true
				continue
			}
			path, _ := strconv.Unquote(spec.Path.Value)
			pkg, err := importer(imports, path)
			if err != nil {
				p.errorf(spec.Path.Pos(), "could not import %s (%s)", path, err)
				importErrors = true
				continue
			}
			// TODO(gri) If a local package name != "." is provided,
			// global identifier resolution could proceed even if the
			// import failed. Consider adjusting the logic here a bit.

			// local name overrides imported package name
			name := pkg.Name
			if spec.Name != nil {
				name = spec.Name.Name
			}

			// add import to file scope
			if name == "." {
				// merge imported scope with file scope
				for _, obj := range pkg.Data.(*Scope).Objects {
					p.declare(fileScope, pkgScope, obj)
				}
			} else if name != "_" {
				// declare imported package object in file scope
				// (do not re-use pkg in the file scope but create
				// a new object instead; the Decl field is different
				// for different files)
				obj := NewObj(Pkg, name)
				obj.Decl = spec
				obj.Data = pkg.Data
				p.declare(fileScope, pkgScope, obj)
			}
		}

		// resolve identifiers
		if importErrors {
			// don't use the universe scope without correct imports
			// (objects in the universe may be shadowed by imports;
			// with missing imports, identifiers might get resolved
			// incorrectly to universe objects)
			pkgScope.Outer = nil
		}
		i := 0
		for _, ident := range file.Unresolved {
			if !resolve(fileScope, ident) {
				p.errorf(ident.Pos(), "undeclared name: %s", ident.Name)
				file.Unresolved[i] = ident
				i++
			}

		}
		file.Unresolved = file.Unresolved[0:i]
		pkgScope.Outer = universe // reset universe scope
	}

	p.errors.Sort()
	return &Package{pkgName, pkgScope, imports, files}, p.errors.Err()
}
