// 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"
	"hash/fnv"
	"io/ioutil"
	"log"
	"os"

	"fidl-lsp/third_party/fidlgen"

	"fidl-lsp/state"
)

// Config keeps track of where the Analyzer can find FIDL tools, as well as the
// root build directory, to which all locations in CompiledLibraries are
// relative.
// This config will be exposed where possible as settings in FIDL LSP client IDE
// extensions.
type Config struct {
	BuildRootDir   string
	FidlcPath      string
	FidlLintPath   string
	FidlFormatPath string
}

// A Library is a set of information about a FIDL library, including build
// information (files and dependencies), the location of its JSON IR if it
// exists (`json`), its deserialized JSON IR (`ir`), and any diagnostics on it.
// `deps` and `files` are treated as sets.
type Library struct {
	name fidlgen.LibraryName
	deps map[fidlgen.LibraryName]bool
	// This library's constituent files in the form of absolute paths
	files   map[string]bool
	json    string
	ir      *FidlLibrary // nil if not yet imported
	diags   map[state.FileID][]Diagnostic
	symbols symbolMap
}

// Analyzer compiles FIDL libraries and extracts analyses from them, including
// diagnostics.
// * inputFilesFIDL is a map from documents open in the editor to the absolute
//   filepath of the corresponding temporary file that Analyzer uses as input
//   for fidlc, etc.
// * inputFileJSON is a map from FIDL library name to an absolute filepath to
//   its JSON IR.
type Analyzer struct {
	// Where to find the fuchsia directory and FIDL tools.
	cfg Config

	// A map from library name (string), like "zx", to a set of data about that
	// library: the FIDL files it includes, its JSON IR, its dependencies, its
	// JSON IR, and diagnostics returned on it from fidlc and fidl-lint.
	libs []*Library

	// A map from open files to their corresponding tmp file used by the
	// Analyzer as an input file for fidlc, fidl-lint, fidl-format, etc.
	// Key is an lsp.DocumentURI, value is an absolute filepath.
	inputFilesFIDL map[state.FileID]string

	// A map from library name to the corresponding tmp file used for their JSON
	// IR.
	inputFilesJSON map[fidlgen.LibraryName]string
}

// NewAnalyzer returns an Analyzer initialized with the set of CompiledLibraries
// passed in.
func NewAnalyzer(cfg Config) *Analyzer {
	a := &Analyzer{
		cfg:            cfg,
		libs:           []*Library{},
		inputFilesFIDL: make(map[state.FileID]string),
		inputFilesJSON: make(map[fidlgen.LibraryName]string),
	}
	return a
}

// ImportCompiledLibraries adds the info for the compiled FIDL libraries in
// `compiledLibraries` to the Analyzer's set of libraries.
func (a *Analyzer) ImportCompiledLibraries(compiledLibraries CompiledLibraries) {
	// TODO(fxbug.dev/55060): currently this tries to reconcile the new set of
	// compiled libraries with the libraries already cached in a.libs, by
	// merging files and deps for libraries that are the same.
	// However, it might be a cleaner approach just to clear a.libs before
	// importing a new set.

	for _, compiledLib := range compiledLibraries {
		name, err := fidlgen.ReadLibraryName(compiledLib.Name)
		if err != nil {
			log.Printf("could not import compiled library `%s`: %s\n", compiledLib.Name, err)
			continue
		}

		var lib *Library
		var alreadyImported bool
		// Check if we already have this library imported.
		if len(compiledLib.Files) > 0 {
			for _, file := range compiledLib.Files {
				lib, alreadyImported = a.getLibraryWithFile(name, state.PathToFileID(file))
				if alreadyImported {
					break
				}
			}
		}
		if !alreadyImported {
			lib = &Library{
				name:  name,
				deps:  make(map[fidlgen.LibraryName]bool, len(compiledLib.Deps)),
				files: make(map[string]bool, len(compiledLib.Files)),
				json:  compiledLib.JSON,
			}
			a.libs = append(a.libs, lib)
		}

		// Whether or not the library was previously imported, we add all the
		// deps and files from the CompiledLibrary.
		if lib.json == "" {
			lib.json = compiledLib.JSON
		}
		for _, dep := range compiledLib.Deps {
			lib.deps[fidlgen.MustReadLibraryName(dep)] = true
		}
		for _, file := range compiledLib.Files {
			// If the file is already included as a replaced tmp input file,
			// don't also include the duplicate.
			if _, ok := a.inputFilesFIDL[state.PathToFileID(file)]; ok {
				continue
			}
			lib.files[file] = true
		}
	}
}

// SetConfig updates the Analyzer's configuration settings.
// Allows the LSP server to update the Analyzer's configuration settings when
// the client updates their settings.
func (a *Analyzer) SetConfig(cfg Config) {
	// The client sends over all settings at once every time but we want to
	// ignore ones that are "unset" -- i.e. equal to the empty string.
	if cfg.BuildRootDir != "" {
		a.cfg.BuildRootDir = cfg.BuildRootDir
	}
	if cfg.FidlcPath != "" {
		a.cfg.FidlcPath = cfg.FidlcPath
	}
	if cfg.FidlLintPath != "" {
		a.cfg.FidlLintPath = cfg.FidlLintPath
	}
	if cfg.FidlFormatPath != "" {
		a.cfg.FidlFormatPath = cfg.FidlFormatPath
	}
}

// getLibrary looks up the library with `name` in a.libs. It does this with an
// imperfect "heuristic" -- return the first library with a matching name --
// imperfect because FIDL library names are not required to be unique. This
// method essentially assumes that they are unique.
//
// Ideally, everywhere getLibrary is called should instead use the
// (*Analyzer).getLibraryWithFile method, since this is guaranteed to be unique.
// Calls to getLibrary should include a comment explaining why it's necessary.
func (a *Analyzer) getLibrary(name fidlgen.LibraryName) (*Library, bool) {
	for _, lib := range a.libs {
		if lib.name == name {
			return lib, true
		}
	}
	return nil, false
}

// getLibraryWithFile looks for a library in a.libs whose name matches `name`
// and which contains a file with the path specified.
//
// This allows a more precise search than getLibrary, since library name + file
// path together is guaranteed to be unique (a file only belongs to one FIDL
// library).
func (a *Analyzer) getLibraryWithFile(name fidlgen.LibraryName, path state.FileID) (*Library, bool) {
	// If there is a corresponding temporary input file used by the Analyzer,
	// use that to lookup the library in a.libs.
	inputFilePath, hadTmpFile := a.inputFilesFIDL[path]

	// Also, try to convert the file to an absolute filepath.
	// The Analyzer stores filepaths for the last analysis of the library, so if
	// files have been changed and are now stored as temporary input file, there
	// could be a mix of tmp files and absolute filepaths.
	// We check for both.
	absPath, err := state.FileIDToPath(path)

	// If we can't find either a temporary file path to lookup, or the absolute
	// file path, we fall back to using the getLibrary method, which doesn't
	// parameterize on a file path.
	if err != nil && !hadTmpFile {
		return a.getLibrary(name)
	}

	for _, lib := range a.libs {
		if lib.name == name {
			for libFile := range lib.files {
				if libFile == inputFilePath || libFile == absPath {
					return lib, true
				}
			}
		}
	}
	return nil, false
}

// Analyze compiles and generates an analysis for the file at `path` in the
// FileSystem. This currently includes compiling the library the file belongs to
// and obtaining diagnostics on it.
// Analyze only uses read access to the FileSystem.
func (a *Analyzer) Analyze(fs *state.FileSystem, path state.FileID) error {
	inputFilePath, err := a.writeFileToTmp(fs, path)
	if err != nil {
		return fmt.Errorf("failed to write file `%s` to tmp: %s", path, err)
	}

	// Add this file and its deps to its Library
	// TODO: do this on setup with all files in workspace
	file, err := fs.File(path)
	if err != nil {
		return fmt.Errorf("could not find file `%s`", path)
	}
	if libName, err := state.LibraryOfFile(file); err == nil {
		// If this file is not already part of a library, either add it to its
		// existing library or, if its library does not exist yet, create a new
		// one.
		var lib *Library
		lib, ok := a.getLibraryWithFile(libName, path)
		if !ok {
			// We don't use getLibraryWithFile here because we have not yet added `file`
			// to its library.
			lib, ok = a.getLibrary(libName)
			if !ok {
				lib = &Library{
					name:  libName,
					deps:  make(map[fidlgen.LibraryName]bool),
					files: make(map[string]bool),
					diags: make(map[state.FileID][]Diagnostic),
				}
				a.libs = append(a.libs, lib)
			}
		}

		// If the file currently being edited was already part of lib.files,
		// delete that and replace it with the temporary/edited version.
		if absPath, err := state.FileIDToPath(path); err != nil {
			log.Printf("error parsing: %s\n", err)
		} else {
			if _, ok := lib.files[absPath]; ok {
				delete(lib.files, absPath)
			}
		}

		lib.files[inputFilePath] = true
		imports := state.ParsePlatformImportsMatch(file)
		for _, dep := range imports {
			lib.deps[fidlgen.LibraryName(dep.Lib)] = true
		}
	}

	// Compile the file's library
	compileResult, err := a.compile(fs, path)
	if err != nil {
		return fmt.Errorf("error on analysis: %s", err)
	}

	compileResult.lib.diags = compileResult.diags
	return nil
}

// Cleanup deletes all temporary files Analyzer created during its lifetime to
// compile FIDL libraries.
func (a *Analyzer) Cleanup() {
	for _, path := range a.inputFilesFIDL {
		err := os.Remove(path)
		if err != nil {
			log.Print(err)
		}
	}
	for _, path := range a.inputFilesJSON {
		err := os.Remove(path)
		if err != nil {
			log.Print(err)
		}
	}
}

// writeFileToTmp writes the in-memory file indexed by `path` to a temporary
// file on disk, in order to enable invoking some command on it in a separate
// process, e.g. fidlc, fidl-format, etc.
func (a *Analyzer) writeFileToTmp(fs *state.FileSystem, path state.FileID) (string, error) {
	if _, ok := a.inputFilesFIDL[path]; !ok {
		a.inputFilesFIDL[path] = fmt.Sprintf("/tmp/%d.fidl", hash(string(path)))
	}

	file, err := fs.File(path)
	if err != nil {
		return "", fmt.Errorf("could not find file `%s`", path)
	}

	// TODO: Can we do 0644 with os.FileMode(os.O_FLAGS)?
	if err := ioutil.WriteFile(a.inputFilesFIDL[path], []byte(file), 0644); err != nil {
		return "", fmt.Errorf("error writing file `%s` to tmp directory: %s", path, err)
	}
	return a.inputFilesFIDL[path], nil
}

func (a *Analyzer) inputFileToFileID(inputFilePath string) (state.FileID, error) {
	for fileID, inputFile := range a.inputFilesFIDL {
		if inputFile == inputFilePath {
			return fileID, nil
		}
	}
	return "", fmt.Errorf("could not find input file `%s`", inputFilePath)
}

// pathToJSON returns the path to the tmp file where the Analyzer saved the JSON
// IR for the library `lib`, or, if there is not a saved JSON file, generates
// a path. It is used for fidlc invocations and for importing libraries' JSON
// IR.
func (a *Analyzer) pathToJSON(lib fidlgen.LibraryName) string {
	if path, ok := a.inputFilesJSON[lib]; ok {
		return path
	}
	a.inputFilesJSON[lib] = fmt.Sprintf("/tmp/%d.json", hash(lib.FullyQualifiedName()))
	return a.inputFilesJSON[lib]
}

func hash(s string) uint32 {
	h := fnv.New32a()
	h.Write([]byte(s))
	return h.Sum32()
}
