// 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"
	"encoding/json"
	"fmt"
	"log"
	"os"

	fidlcommon "fidl-lsp/third_party/common"
	"github.com/sourcegraph/go-lsp"
	"github.com/sourcegraph/jsonrpc2"

	"fidl-lsp/analysis"
	"fidl-lsp/state"
)

// LspServer is a wrapper around a LangHandler.
// It is the entry point for all LSP communication with the client.
type LspServer struct {
	jsonrpc2.Handler
}

// LangHandler implements jsonrpc2.Handler, an interface with one Handle method.
// It fields all LSP requests from the client, and sends back responses and
// notifications.
//
// LangHandler has a *state.FileSystem, which keeps track of the the language
// editor's open files (in the future, to support concurrency, this state can be
// wrapped in e.g. an RWLock).
//
// LangHandler also has an *analysis.Analyzer,
// which is used to compile and extract insights from files being edited.
type LangHandler struct {
	cfg      Config
	init     *lsp.InitializeParams
	shutdown bool

	log *log.Logger

	fs *state.FileSystem

	analyzer *analysis.Analyzer
}

// Assert that LangHandler implements the jsonrpc2.Handler interface
var _ jsonrpc2.Handler = (*LangHandler)(nil)

type Config struct {
	serverCapabilities serverCapabilities

	// The base URI for reference links. Currently we linkify Fuchsia platform
	// library imports, and the links point to the SDK docs.
	baseRefURI string
}

func (c *Config) FormatRefURI(libraryName fidlcommon.LibraryName) string {
	return c.baseRefURI + libraryName.FullyQualifiedName()
}

// NewDefaultConfig returns a default configuration for the language server.
func NewDefaultConfig() Config {
	return Config{
		serverCapabilities: serverCapabilities{
			DefinitionProvider:         true,
			DocumentFormattingProvider: true,
			DocumentLinkProvider:       &documentLinkOptions{},
			HoverProvider:              true,
			ReferencesProvider:         true,
			TextDocumentSync: &lsp.TextDocumentSyncOptionsOrKind{
				Options: &lsp.TextDocumentSyncOptions{
					OpenClose: true,
					Change:    lsp.TDSKIncremental,
				},
			},
		},
		baseRefURI: "https://fuchsia.dev/reference/fidl/",
	}
}

// NewLangHandler returns a LangHandler with the given configuration, logger,
// and set of CompiledLibraries.
func NewLangHandler(cfg Config, trace *log.Logger, analyzer *analysis.Analyzer) *LangHandler {
	return &LangHandler{
		log:      trace,
		cfg:      cfg,
		fs:       state.NewFileSystem(),
		analyzer: analyzer,
	}
}

// Handle fields an LSP request or notification.
// If there is an internal server error, it will be logged and an empty response
// will be sent to the client. If there is an error in the request, an error
// reponse will be sent.
func (h *LangHandler) Handle(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) {
	if resp, handleErr := h.handle(ctx, conn, req); handleErr == nil {
		if resp != nil {
			if err := conn.Reply(ctx, req.ID, resp); err != nil {
				h.log.Printf("error on conn.Reply: %s\n", err)
			}
		}
	} else {
		switch handleErr.(type) {
		case *jsonrpc2.Error:
			h.log.Printf("got a request we couldn't handle: %s\n", req.Method)
			if err := conn.ReplyWithError(ctx, req.ID, handleErr.(*jsonrpc2.Error)); err != nil {
				h.log.Printf("error on conn.ReplyWithError: %s\n", err)
			}
		default:
			// If the error is not a jsonrpc2.Error, this means that we had an
			// internal server error and were unable to meet the request. Rather
			// than pass that error on to the client, we should log the error
			// and reply with an empty response so the client is not waiting for
			// a response.
			h.log.Printf("err on handling `%s`: %s\n", req.Method, handleErr)
			if err := conn.Reply(ctx, req.ID, resp); err != nil {
				h.log.Printf("error on conn.Reply: %s\n", err)
			}
		}
	}
}

// Notify sends an LSP notification.
func (h *LangHandler) Notify(ctx context.Context, conn *jsonrpc2.Conn, method string, notif interface{}) {
	if err := conn.Notify(ctx, method, notif); err != nil {
		h.log.Printf("error on conn.Reply: %s\n", err)
	}
}

// The general pattern of the `handle` callback is as follows:
//
// * receive a notification from the client indicating a change of state -->
//   pass the change to the FileSystem -->
//   trigger a re-analysis of the file that was changed -->
//   publish diagnostics on that file.
//
// * receive a request from the client -->
//   request the relevant analysis from the Analyzer, passing it a snapshot of
//   the state of the FileSystem -->
//   wrap the analysis in relevant LSP type/object and send to the client.
func (h *LangHandler) handle(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) (result interface{}, err error) {
	// TODO: locking over `h`
	switch req.Method {
	case "initialize":
		// TODO: if server receives any request before `initialize`, it should
		// respond with error code: -32002
		if h.init != nil {
			return nil, &jsonrpc2.Error{
				Code:    jsonrpc2.CodeInvalidRequest,
				Message: "language server is already initialized",
			}
		}
		if req.Params == nil {
			return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
		}
		var params lsp.InitializeParams
		if err := json.Unmarshal(*req.Params, &params); err != nil {
			return nil, err
		}
		h.init = &params
		return initializeResult{Capabilities: h.cfg.serverCapabilities}, nil

	case "initialized":
		// A notification that the client is ready to receive requests. Ignore
		return nil, nil

	case "shutdown":
		// TODO: if server receives any request after `shutdown`, it should
		// respond with an error: InvalidRequest.
		h.shutdown = true
		h.analyzer.Cleanup()
		return nil, nil

	case "exit":
		if h.shutdown {
			os.Exit(0)
		} else {
			os.Exit(1)
		}
		return nil, nil

	case "textDocument/didOpen":
		if req.Params == nil {
			return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
		}
		var params lsp.DidOpenTextDocumentParams
		if err := json.Unmarshal(*req.Params, &params); err != nil {
			return nil, err
		}

		h.handleOpenFile(params)
		if err := h.analyzer.Analyze(h.fs, state.FileID(params.TextDocument.URI)); err != nil {
			h.log.Println(err)
		}
		h.publishDiagnostics(ctx, conn, params.TextDocument.URI)
		return nil, nil

	case "textDocument/didClose":
		if req.Params == nil {
			return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
		}
		var params lsp.DidCloseTextDocumentParams
		if err := json.Unmarshal(*req.Params, &params); err != nil {
			return nil, err
		}

		h.handleCloseFile(params)
		// TODO: remove diagnostics associated with this file?
		return nil, nil

	case "textDocument/didChange":
		if req.Params == nil {
			return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
		}
		var params lsp.DidChangeTextDocumentParams
		if err := json.Unmarshal(*req.Params, &params); err != nil {
			return nil, err
		}

		h.handleDidChange(params)
		if err := h.analyzer.Analyze(h.fs, state.FileID(params.TextDocument.URI)); err != nil {
			h.log.Println(err)
		}
		h.publishDiagnostics(ctx, conn, params.TextDocument.URI)
		return nil, nil

	case "textDocument/definition":
		if req.Params == nil {
			return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
		}
		var params lsp.TextDocumentPositionParams
		if err := json.Unmarshal(*req.Params, &params); err != nil {
			return nil, err
		}

		return h.handleDefinition(params)

	case "textDocument/documentLink":
		if req.Params == nil {
			return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
		}
		var params documentLinkParams
		if err := json.Unmarshal(*req.Params, &params); err != nil {
			return nil, err
		}

		return h.handleDocumentLinks(params)

	case "textDocument/formatting":
		if req.Params == nil {
			return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
		}
		var params lsp.DocumentFormattingParams
		if err := json.Unmarshal(*req.Params, &params); err != nil {
			return nil, err
		}

		return h.handleFormat(params)

	case "textDocument/hover":
		if req.Params == nil {
			return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
		}
		var params lsp.TextDocumentPositionParams
		if err := json.Unmarshal(*req.Params, &params); err != nil {
			return nil, err
		}

		return h.handleHover(params)

	case "textDocument/references":
		if req.Params == nil {
			return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
		}
		var params lsp.TextDocumentPositionParams
		if err := json.Unmarshal(*req.Params, &params); err != nil {
			return nil, err
		}

		return h.handleReferences(params)

	default:
		return nil, &jsonrpc2.Error{
			Code:    jsonrpc2.CodeMethodNotFound,
			Message: fmt.Sprintf("method not supported: %s", req.Method),
		}
	}
}
