// Copyright 2019 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 source

import (
	"context"
	"go/ast"
	"go/types"

	"golang.org/x/tools/go/types/objectpath"
	"golang.org/x/tools/internal/lsp/telemetry"
	"golang.org/x/tools/internal/telemetry/log"
	"golang.org/x/tools/internal/telemetry/trace"
	errors "golang.org/x/xerrors"
)

// ReferenceInfo holds information about reference to an identifier in Go source.
type ReferenceInfo struct {
	Name string
	mappedRange
	ident         *ast.Ident
	obj           types.Object
	pkg           Package
	isDeclaration bool
}

// References returns a list of references for a given identifier within the packages
// containing i.File. Declarations appear first in the result.
func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, error) {
	ctx, done := trace.StartSpan(ctx, "source.References")
	defer done()

	// If the object declaration is nil, assume it is an import spec and do not look for references.
	if i.Declaration.obj == nil {
		return nil, errors.Errorf("no references for an import spec")
	}
	info := i.pkg.GetTypesInfo()
	if info == nil {
		return nil, errors.Errorf("package %s has no types info", i.pkg.PkgPath())
	}
	var searchpkgs []Package
	if i.Declaration.obj.Exported() {
		// Only search all packages if the identifier is exported.
		reverseDeps, err := i.Snapshot.GetReverseDependencies(ctx, i.pkg.ID())
		if err != nil {
			return nil, err
		}
		for _, id := range reverseDeps {
			ph, err := i.Snapshot.PackageHandle(ctx, id)
			if err != nil {
				log.Error(ctx, "References: no CheckPackageHandle", err, telemetry.Package.Of(id))
				continue
			}
			pkg, err := ph.Check(ctx)
			if err != nil {
				log.Error(ctx, "References: no Package", err, telemetry.Package.Of(id))
				continue
			}
			searchpkgs = append(searchpkgs, pkg)
		}
	}
	// Add the package in which the identifier is declared.
	searchpkgs = append(searchpkgs, i.pkg)

	var references []*ReferenceInfo
	for _, pkg := range searchpkgs {
		for ident, obj := range pkg.GetTypesInfo().Uses {
			if !sameObj(obj, i.Declaration.obj) {
				continue
			}
			rng, err := posToMappedRange(i.Snapshot.View(), pkg, ident.Pos(), ident.End())
			if err != nil {
				return nil, err
			}
			references = append(references, &ReferenceInfo{
				Name:        ident.Name,
				ident:       ident,
				pkg:         i.pkg,
				obj:         obj,
				mappedRange: rng,
			})
		}
	}
	return references, nil
}

// sameObj returns true if obj is the same as declObj.
// Objects are the same if either they have they have objectpaths
// and their objectpath and package are the same; or if they don't
// have object paths and they have the same Pos and Name.
func sameObj(obj, declObj types.Object) bool {
	if obj == nil || declObj == nil {
		return false
	}
	// TODO(suzmue): support the case where an identifier may have two different
	// declaration positions.
	if obj.Pkg() == nil || declObj.Pkg() == nil {
		if obj.Pkg() != declObj.Pkg() {
			return false
		}
	} else if obj.Pkg().Path() != declObj.Pkg().Path() {
		return false
	}
	objPath, operr := objectpath.For(obj)
	declObjPath, doperr := objectpath.For(declObj)
	if operr != nil || doperr != nil {
		return obj.Pos() == declObj.Pos() && obj.Name() == declObj.Name()
	}
	return objPath == declObjPath
}
