// 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"
	"log"

	"fidl-lsp/third_party/fidlgen"

	"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 := fidlgen.ReadLibraryName(sym.Name)
	if err == nil {
		// TODO: We could use getLibraryWithFile here, but it would be more
		// complicated: if this library name is a declaration, we should pass it
		// the file the symbol is in; but if it's a library import, we should
		// pass it a file of that imported library.
		if lib, isLib := a.getLibrary(libName); isLib {
			return a.declarationsOfLibrary(fs, lib), 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,
		)
	}

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

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

func (a *Analyzer) declarationsOfLibrary(fs *state.FileSystem, lib *Library) []state.Location {
	files := []state.FileID{}
	for file := range 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 {
				log.Printf("could not read in file `%s`: %s", fileID, err)
				continue
			}
			file = string(bytes)
		}

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