// Copyright 2020 The Fuchsia 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 analysis

import (
	"fmt"
	"io/ioutil"

	fidlcommon "fidl-lsp/third_party/common"

	"fidl-lsp/state"
)

// DefinitionOfSymbol returns the location (or locations) where the given symbol
// is defined, as long as that location is available to the Analyzer (i.e. in
// a.libs somewhere).
//
// For a library name, e.g. `fuchsia.foo`, DefinitionOfSymbol returns the
// locations of the `library` declarations for each file in that library.
//
// DefinitionOfSymbol only works for library names and top-level names: enums,
// bits, structs, protocols, etc. -- not for member names. For example, it can
// find the definition of `Foo` in the following example:
//
// 		protocol P {
// 			Method(Foo foo);
// 		};
//
// But it can't find the definition of `B.FOO`:
//
// 		bits B {
//			FOO = 0;
// 		}
//		const ZERO = B.FOO;
func (a *Analyzer) DefinitionOfSymbol(fs *state.FileSystem, sym state.Symbol) ([]state.Location, error) {
	// If `sym` is a library name, return locations pointing at all the files in
	// the library (specifically, pointing at their `library` declarations).
	libName, err := fidlcommon.ReadLibraryName(sym.Name)
	if err == nil {
		if _, isLib := a.libs[libName]; isLib {
			return a.declarationsOfLibrary(fs, libName), nil
		}
	}

	// Otherwise, we assume it is a local or fully-qualified name
	name, err := a.symbolToFullyQualifiedName(fs, sym)
	if err != nil {
		return nil, fmt.Errorf(
			"could not convert symbol `%s` to fully-qualified name: %s",
			sym.Name,
			err,
		)
	}

	symInfo, err := a.lookupSymbolInfo(name)
	if err != nil {
		return nil, fmt.Errorf("could not find definition of symbol `%s`: %s", name.FullyQualifiedName(), err)
	}

	return []state.Location{symInfo.definition}, nil
}

func (a *Analyzer) declarationsOfLibrary(fs *state.FileSystem, lib fidlcommon.LibraryName) []state.Location {
	files := []state.FileID{}
	for file := range a.libs[lib].files {
		// These files are all absolute paths, but some are to temporary input
		// files used by the Analyzer. For these, we want to convert the path
		// to the document URI the editor knows about.
		if fileID, err := a.inputFileToFileID(file); err != nil {
			files = append(files, state.FileID(file))
		} else {
			files = append(files, fileID)
		}
	}

	locs := []state.Location{}
	// Find the `library` declaration in each file
	for _, fileID := range files {
		file, err := fs.File(fileID)
		if err != nil {
			// If we don't have the file in memory, read it in
			bytes, err := ioutil.ReadFile(string(fileID))
			if err != nil {
				continue
			}
			file = string(bytes)
		}

		if libraryMatch, ok := state.ParseLibraryMatch(file); ok {
			locs = append(locs, state.Location{
				FileID: fileID,
				Range:  libraryMatch.Range,
			})
		}
	}
	return locs
}
