// 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 (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os/exec"

	"fidl-lsp/state"
)

// Read in the JSON IR at absolute filepath `jsonPath`.
func (a *Analyzer) importLibrary(jsonPath string) error {
	data, err := ioutil.ReadFile(jsonPath)
	if err != nil {
		return err
	}
	var lib FidlLibrary
	if err := json.Unmarshal(data, &lib); err != nil {
		return err
	}
	// TODO: import more things? files + deps?
	if _, ok := a.libs[LibraryName(lib.Name)]; !ok {
		a.libs[LibraryName(lib.Name)] = &Library{
			json: jsonPath,
		}
	}
	a.libs[LibraryName(lib.Name)].ir = &lib

	// TODO: construct symbol map from JSON IR for the file's library
	return nil
}

type compileResult struct {
	lib   LibraryName
	diags map[state.EditorFile][]Diagnostic
}

// Compile the FIDL library that includes the file at `path`.
// Returns either a compileResult containing the name of the library along with
// any diagnostics returned by fidlc and fidl-lint, or an error if compilation
// fails.
func (a *Analyzer) compile(fs *state.FileSystem, path state.EditorFile) (compileResult, error) {
	var jsonPath string
	file, err := fs.File(path)
	if err != nil {
		return compileResult{}, fmt.Errorf("could not find file `%s`", path)
	}

	libraryName, err := state.LibraryOfFile(file)
	if err != nil {
		return compileResult{}, fmt.Errorf("could not find library name of file `%s`", path)
	}
	jsonPath = a.pathToJSON(LibraryName(libraryName))

	args := append([]string{"--format=json"}, "--json", jsonPath)
	files, err := a.FindDeps(fs, path)
	if err != nil {
		return compileResult{}, fmt.Errorf("could not find dependencies of file `%s`: %s", path, err)
	}
	args = append(args, files...)

	cmd := exec.Command(fidlcPath, args...)
	var stderr bytes.Buffer
	cmd.Stderr = &stderr
	if err := cmd.Run(); err == nil {
		// If fidlc compiled successfully, update a.libs with the compiled JSON IR
		if err := a.importLibrary(jsonPath); err != nil {
			return compileResult{}, fmt.Errorf("error on adding compiled JSON: %s", err)
		}
	}

	diags := make(map[state.EditorFile][]Diagnostic)
	for fileName := range a.libs[LibraryName(libraryName)].files {
		editorFile, err := a.inputFileToEditorFile(fileName)
		if err == nil {
			diags[editorFile] = []Diagnostic{}
		}
	}
	if errorsAndWarnings, err := a.fidlcDiagsFromStderr(stderr.Bytes()); err == nil {
		for editorFile, fileDiags := range errorsAndWarnings {
			if _, ok := diags[editorFile]; !ok {
				diags[editorFile] = []Diagnostic{}
			}
			diags[editorFile] = append(diags[editorFile], fileDiags...)
		}
	}
	if lints, err := a.runFidlLint(a.inputFilesFIDL[path]); err == nil {
		for editorFile, fileDiags := range lints {
			if _, ok := diags[editorFile]; !ok {
				diags[editorFile] = []Diagnostic{}
			}
			diags[editorFile] = append(diags[editorFile], fileDiags...)
		}
	}

	return compileResult{
		lib:   LibraryName(libraryName),
		diags: diags,
	}, nil
}
