// 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 langserver

import (
	"context"
	"fmt"
	"path/filepath"

	"github.com/sourcegraph/go-lsp"
	"github.com/sourcegraph/jsonrpc2"

	"fidl-lsp/analysis"
)

// clientConfig are the configuration settings from the LSP client. These are
// relevant to the Analyzer. If they are left unset, the Analyzer uses its
// defaults.
type clientConfig struct {
	FidlProject string      `json:"fidlProject,omitempty"`
	BuildRoot   string      `json:"projectRoot,omitempty"`
	Tools       toolsConfig `json:"tools,omitempty"`
}

type toolsConfig struct {
	Compiler  string `json:"compiler,omitempty"`
	Linter    string `json:"linter,omitempty"`
	Formatter string `json:"formatter,omitempty"`
}

func (h *LangHandler) requestConfiguration(ctx context.Context, conn *jsonrpc2.Conn) {
	go func() {
		var cfg []clientConfig
		conn.Call(
			ctx,
			"workspace/configuration",
			lsp.ConfigurationParams{
				Items: []lsp.ConfigurationItem{{Section: "fidl"}},
			},
			&cfg,
		)
		if len(cfg) < 1 {
			h.log.Printf("received invalid configuration settings. unable to update\n")
			// Try loading the default fidl_project.json path
			h.loadFidlProject(ctx, conn, h.cfg.fidlProjectPath)
			return
		}
		h.updateConfig(ctx, conn, cfg[0])
	}()
}

func (h *LangHandler) handleDidChangeConfiguration(ctx context.Context, conn *jsonrpc2.Conn, params lsp.DidChangeConfigurationParams) {
	h.log.Printf("updating with new config settings: %#v", params.Settings)

	cfg, ok := params.Settings.([]clientConfig)
	if !ok {
		h.log.Printf("received invalid configuration settings. unable to update\n")
		return
	}
	if len(cfg) < 1 {
		h.log.Printf("received invalid configuration settings. unable to update\n")
		return
	}
	h.updateConfig(ctx, conn, cfg[0])
}

func (h *LangHandler) updateConfig(ctx context.Context, conn *jsonrpc2.Conn, cfg clientConfig) {
	if cfg.FidlProject == "" {
		// FidlProject is unset; try loading the default fidl_project.json path
		h.loadFidlProject(ctx, conn, h.cfg.fidlProjectPath)
	} else {
		h.loadFidlProject(ctx, conn, cfg.FidlProject)
		// If the BuildRoot is unset, set it to the directory containing
		// `FidlProject`
		if cfg.BuildRoot == "" {
			cfg.BuildRoot = filepath.Dir(cfg.FidlProject)
		}
	}

	h.analyzer.SetConfig(analysis.Config{
		BuildRootDir:   cfg.BuildRoot,
		FidlcPath:      cfg.Tools.Compiler,
		FidlLintPath:   cfg.Tools.Linter,
		FidlFormatPath: cfg.Tools.Formatter,
	})

	// Re-analyze files that could have been affected by the new config
	for _, file := range h.fs.Files() {
		if err := h.analyzer.Analyze(h.fs, file); err != nil {
			h.log.Println(err)
		}
		h.publishDiagnostics(ctx, conn, lsp.DocumentURI(file))
	}
}

// loadFidlProject attempts to read in the fidl_project.json file at
// `fidlProjectPath`, and if it can't, it displays an error dialog in the client
// so the user can try to regenerate the file.
func (h *LangHandler) loadFidlProject(ctx context.Context, conn *jsonrpc2.Conn, fidlProjectPath string) {
	fidlProject, err := analysis.LoadFidlProject(fidlProjectPath)
	if err != nil {
		h.log.Printf("failed to parse fidl_project.json at `%s`: %s\n", fidlProjectPath, err)
		h.Notify(ctx, conn, "window/showMessage", lsp.ShowMessageParams{
			Type: lsp.MTError,
			Message: fmt.Sprintf(
				"Failed to load fidl_project.json at '%s'.\n"+
					"To generate this file, run "+
					"`fx gen && fx build build/fidl:validate_fidl_project_json`. "+
					"Alternatively, custom path can be specified in settings.",
				fidlProjectPath,
			),
		})
	}
	h.analyzer.ImportCompiledLibraries(fidlProject)
}
