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

	"fidl-lsp/state"
)

var (
	fuchsiaDir      = os.Getenv("FUCHSIA_DIR")
	outDir          = fuchsiaDir + "/out/default/"
	fidlProjectPath = outDir + "fidl_project.json"
	toolsPath       = fuchsiaDir + "/out/default.zircon/tools/"
	fidlcPath       = toolsPath + "fidlc"
	fidlLintPath    = toolsPath + "fidl-lint"
	fidlFormatPath  = toolsPath + "fidl-format"
)

// A LibraryName is a FIDL library represented by its name (as spelled in its
// `library` declaration, not necessarily matching directory or file names).
type LibraryName 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 {
	deps  map[LibraryName]bool
	files map[string]bool
	json  string
	ir    *FidlLibrary // nil if not yet imported
	diags map[state.EditorFile][]Diagnostic
}

// 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 {
	// 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 map[LibraryName]*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.EditorFile]string

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

// NewAnalyzer returns an Analyzer initialized with the set of CompiledLibraries
// passed in.
func NewAnalyzer(compiledLibraries CompiledLibraries) *Analyzer {
	a := &Analyzer{
		libs:           make(map[LibraryName]*Library),
		inputFilesFIDL: make(map[state.EditorFile]string),
		inputFilesJSON: make(map[LibraryName]string),
	}
	for libName, lib := range compiledLibraries {
		a.libs[libName] = &Library{
			deps:  make(map[LibraryName]bool, len(lib.Deps)),
			files: make(map[string]bool, len(lib.Files)),
			json:  lib.JSON,
		}
		for _, dep := range lib.Deps {
			a.libs[libName].deps[dep] = true
		}
		for _, file := range lib.Files {
			a.libs[libName].files[file] = true
		}
	}
	return a
}

// 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.EditorFile) 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 _, ok := a.libs[LibraryName(libName)]; !ok {
			a.libs[LibraryName(libName)] = &Library{
				deps:  make(map[LibraryName]bool),
				files: make(map[string]bool),
				diags: make(map[state.EditorFile][]Diagnostic),
			}
		}

		lib := a.libs[LibraryName(libName)]
		// 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.EditorFileToPath(path); err == nil {
			if _, ok := lib.files[absPath]; ok {
				delete(lib.files, absPath)
			}
		} else {
			fmt.Fprint(os.Stderr, "error parsing\n")
		}

		lib.files[inputFilePath] = true
		imports := state.ParsePlatformImportsMatch(file)
		for _, dep := range imports {
			lib.deps[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)
	}

	a.libs[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 {
			fmt.Fprintln(os.Stderr, err)
		}
	}
	for _, path := range a.inputFilesJSON {
		err := os.Remove(path)
		if err != nil {
			fmt.Fprintln(os.Stderr, 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.EditorFile) (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) inputFileToEditorFile(inputFilePath string) (state.EditorFile, error) {
	for editorFile, inputFile := range a.inputFilesFIDL {
		if inputFile == inputFilePath {
			return editorFile, 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 LibraryName) string {
	if path, ok := a.inputFilesJSON[lib]; ok {
		return path
	}
	a.inputFilesJSON[lib] = fmt.Sprintf("/tmp/%d.json", hash(string(lib)))
	return a.inputFilesJSON[lib]
}

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