// Copyright (C) 2019 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// langsvr implements a Language Server for the SPIRV assembly language.
package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"os"
	"path"
	"sort"
	"strings"
	"sync"
	"unicode/utf8"

	"github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/parser"
	"github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/schema"

	"github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/jsonrpc2"
	lsp "github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/protocol"
)

const (
	enableDebugLogging = false
)

// rSpy is a reader 'spy' that wraps an io.Reader, and logs all data that passes
// through it.
type rSpy struct {
	prefix string
	r      io.Reader
}

func (s rSpy) Read(p []byte) (n int, err error) {
	n, err = s.r.Read(p)
	log.Printf("%v %v", s.prefix, string(p[:n]))
	return n, err
}

// wSpy is a reader 'spy' that wraps an io.Writer, and logs all data that passes
// through it.
type wSpy struct {
	prefix string
	w      io.Writer
}

func (s wSpy) Write(p []byte) (n int, err error) {
	n, err = s.w.Write(p)
	log.Printf("%v %v", s.prefix, string(p))
	return n, err
}

// main entry point.
func main() {
	log.SetOutput(io.Discard)
	if enableDebugLogging {
		// create a log file in the executable's directory.
		if logfile, err := os.Create(path.Join(path.Dir(os.Args[0]), "log.txt")); err == nil {
			defer logfile.Close()
			log.SetOutput(logfile)
		}
	}

	log.Println("language server started")

	stream := jsonrpc2.NewHeaderStream(rSpy{"IDE", os.Stdin}, wSpy{"LS", os.Stdout})
	s := server{
		files: map[string]*file{},
	}
	s.ctx, s.conn, s.client = lsp.NewServer(context.Background(), stream, &s)
	if err := s.conn.Run(s.ctx); err != nil {
		log.Panicln(err)
		os.Exit(1)
	}

	log.Println("language server stopped")
}

type server struct {
	ctx    context.Context
	conn   *jsonrpc2.Conn
	client lsp.Client

	files      map[string]*file
	filesMutex sync.Mutex
}

// file represents a source file
type file struct {
	fullRange parser.Range
	res       parser.Results
}

// tokAt returns the parser token at the given position lp
func (f *file) tokAt(lp lsp.Position) *parser.Token {
	toks := f.res.Tokens
	p := parser.Position{Line: int(lp.Line) + 1, Column: int(lp.Character) + 1}
	i := sort.Search(len(toks), func(i int) bool { return p.LessThan(toks[i].Range.End) })
	if i == len(toks) {
		return nil
	}
	if toks[i].Range.Contains(p) {
		return toks[i]
	}
	return nil
}

func (s *server) DidChangeWorkspaceFolders(ctx context.Context, p *lsp.DidChangeWorkspaceFoldersParams) error {
	log.Println("server.DidChangeWorkspaceFolders()")
	return nil
}
func (s *server) Initialized(ctx context.Context, p *lsp.InitializedParams) error {
	log.Println("server.Initialized()")
	return nil
}
func (s *server) Exit(ctx context.Context) error {
	log.Println("server.Exit()")
	return nil
}
func (s *server) DidChangeConfiguration(ctx context.Context, p *lsp.DidChangeConfigurationParams) error {
	log.Println("server.DidChangeConfiguration()")
	return nil
}
func (s *server) DidOpen(ctx context.Context, p *lsp.DidOpenTextDocumentParams) error {
	log.Println("server.DidOpen()")
	return s.processFile(ctx, p.TextDocument.URI, p.TextDocument.Text)
}
func (s *server) DidChange(ctx context.Context, p *lsp.DidChangeTextDocumentParams) error {
	log.Println("server.DidChange()")
	return s.processFile(ctx, p.TextDocument.URI, p.ContentChanges[0].Text)
}
func (s *server) DidClose(ctx context.Context, p *lsp.DidCloseTextDocumentParams) error {
	log.Println("server.DidClose()")
	return nil
}
func (s *server) DidSave(ctx context.Context, p *lsp.DidSaveTextDocumentParams) error {
	log.Println("server.DidSave()")
	return nil
}
func (s *server) WillSave(ctx context.Context, p *lsp.WillSaveTextDocumentParams) error {
	log.Println("server.WillSave()")
	return nil
}
func (s *server) DidChangeWatchedFiles(ctx context.Context, p *lsp.DidChangeWatchedFilesParams) error {
	log.Println("server.DidChangeWatchedFiles()")
	return nil
}
func (s *server) Progress(ctx context.Context, p *lsp.ProgressParams) error {
	log.Println("server.Progress()")
	return nil
}
func (s *server) SetTraceNotification(ctx context.Context, p *lsp.SetTraceParams) error {
	log.Println("server.SetTraceNotification()")
	return nil
}
func (s *server) LogTraceNotification(ctx context.Context, p *lsp.LogTraceParams) error {
	log.Println("server.LogTraceNotification()")
	return nil
}
func (s *server) Implementation(ctx context.Context, p *lsp.ImplementationParams) ([]lsp.Location, error) {
	log.Println("server.Implementation()")
	return nil, nil
}
func (s *server) TypeDefinition(ctx context.Context, p *lsp.TypeDefinitionParams) ([]lsp.Location, error) {
	log.Println("server.TypeDefinition()")
	return nil, nil
}
func (s *server) DocumentColor(ctx context.Context, p *lsp.DocumentColorParams) ([]lsp.ColorInformation, error) {
	log.Println("server.DocumentColor()")
	return nil, nil
}
func (s *server) ColorPresentation(ctx context.Context, p *lsp.ColorPresentationParams) ([]lsp.ColorPresentation, error) {
	log.Println("server.ColorPresentation()")
	return nil, nil
}
func (s *server) FoldingRange(ctx context.Context, p *lsp.FoldingRangeParams) ([]lsp.FoldingRange, error) {
	log.Println("server.FoldingRange()")
	return nil, nil
}
func (s *server) Declaration(ctx context.Context, p *lsp.DeclarationParams) ([]lsp.DeclarationLink, error) {
	log.Println("server.Declaration()")
	return nil, nil
}
func (s *server) SelectionRange(ctx context.Context, p *lsp.SelectionRangeParams) ([]lsp.SelectionRange, error) {
	log.Println("server.SelectionRange()")
	return nil, nil
}
func (s *server) Initialize(ctx context.Context, p *lsp.ParamInitia) (*lsp.InitializeResult, error) {
	log.Println("server.Initialize()")
	res := lsp.InitializeResult{
		Capabilities: lsp.ServerCapabilities{
			TextDocumentSync: lsp.TextDocumentSyncOptions{
				OpenClose: true,
				Change:    lsp.Full, // TODO: Implement incremental
			},
			HoverProvider:              true,
			DefinitionProvider:         true,
			ReferencesProvider:         true,
			RenameProvider:             true,
			DocumentFormattingProvider: true,
			CompletionProvider: &lsp.CompletionOptions{
				TriggerCharacters: []string{"%"},
				ResolveProvider:   false,
			},
		},
	}
	return &res, nil
}
func (s *server) Shutdown(ctx context.Context) error {
	log.Println("server.Shutdown()")
	return nil
}
func (s *server) WillSaveWaitUntil(ctx context.Context, p *lsp.WillSaveTextDocumentParams) ([]lsp.TextEdit, error) {
	log.Println("server.WillSaveWaitUntil()")
	return nil, nil
}

func markdownOpcode(op *schema.Opcode) string {
	sb := strings.Builder{}
	sb.WriteString(fmt.Sprintf("**%s** (%s)\n\n", op.Opname, op.Class))

	for idx, operand := range op.Operands {
		sb.WriteString(fmt.Sprintf("Operand %d%s: ", idx, operand.Quantifier))
		sb.WriteString(fmt.Sprintf("%s (%s)\n", operand.Name, operand.Kind.Kind))
	}

	return sb.String()
}

func (s *server) Completion(ctx context.Context, p *lsp.CompletionParams) (*lsp.CompletionList, error) {
	log.Println("server.Completion()")
	f := s.getFile(p.TextDocument.URI)
	if f == nil {
		return nil, fmt.Errorf("Unknown file")
	}

	if p.Context.TriggerCharacter == "%" {
		idents := []lsp.CompletionItem{}
		for name, ident := range f.res.Identifiers {
			idents = append(idents, lsp.CompletionItem{
				Label:         name,
				Kind:          6,
				Documentation: ident.Definition.Range.Text(f.res.Lines),
			})
		}
		res := &lsp.CompletionList{
			IsIncomplete: false,
			Items:        idents,
		}

		return res, nil
	}

	opcodes := []lsp.CompletionItem{}
	for name, opcode := range schema.Opcodes {
		opcodes = append(opcodes, lsp.CompletionItem{
			Label:         name,
			Kind:          3,
			Documentation: markdownOpcode(opcode),
		})
	}
	res := &lsp.CompletionList{
		IsIncomplete: false,
		Items:        opcodes,
	}
	return res, nil
}
func (s *server) Resolve(ctx context.Context, p *lsp.CompletionItem) (*lsp.CompletionItem, error) {
	log.Println("server.Resolve()")
	return nil, nil
}
func (s *server) Hover(ctx context.Context, p *lsp.HoverParams) (*lsp.Hover, error) {
	log.Println("server.Hover()")
	f := s.getFile(p.TextDocument.URI)
	if f == nil {
		return nil, fmt.Errorf("Unknown file")
	}

	if tok := f.tokAt(p.Position); tok != nil {
		sb := strings.Builder{}
		switch v := f.res.Mappings[tok].(type) {
		default:
			sb.WriteString(fmt.Sprintf("<Unhandled type '%T'>", v))
		case *parser.Instruction:
			sb.WriteString(markdownOpcode(v.Opcode))
		case *parser.Identifier:
			sb.WriteString(fmt.Sprintf("```\n%v\n```", v.Definition.Range.Text(f.res.Lines)))
		case *parser.Operand:
			if v.Name != "" {
				sb.WriteString(strings.Trim(v.Name, `'`))
				sb.WriteString("\n\n")
			}

			switch v.Kind.Category {
			case schema.OperandCategoryBitEnum:
			case schema.OperandCategoryValueEnum:
				sb.WriteString("```\n")
				sb.WriteString(strings.Trim(v.Kind.Kind, `'`))
				sb.WriteString("\n```")
			case schema.OperandCategoryID:
				if s := tok.Text(f.res.Lines); s != "" {
					if id, ok := f.res.Identifiers[s]; ok && id.Definition != nil {
						sb.WriteString("```\n")
						sb.WriteString(id.Definition.Range.Text(f.res.Lines))
						sb.WriteString("\n```")
					}
				}
			case schema.OperandCategoryLiteral:
			case schema.OperandCategoryComposite:
			}
		case nil:
		}

		if sb.Len() > 0 {
			res := lsp.Hover{
				Contents: lsp.MarkupContent{
					Kind:  "markdown",
					Value: sb.String(),
				},
			}
			return &res, nil
		}
	}

	return nil, nil
}
func (s *server) SignatureHelp(ctx context.Context, p *lsp.SignatureHelpParams) (*lsp.SignatureHelp, error) {
	log.Println("server.SignatureHelp()")
	return nil, nil
}
func (s *server) Definition(ctx context.Context, p *lsp.DefinitionParams) ([]lsp.Location, error) {
	log.Println("server.Definition()")
	if f := s.getFile(p.TextDocument.URI); f != nil {
		if tok := f.tokAt(p.Position); tok != nil {
			if s := tok.Text(f.res.Lines); s != "" {
				if id, ok := f.res.Identifiers[s]; ok {
					loc := lsp.Location{
						URI:   p.TextDocument.URI,
						Range: rangeToLSP(id.Definition.Range),
					}
					return []lsp.Location{loc}, nil
				}
			}
		}
	}
	return nil, nil
}
func (s *server) References(ctx context.Context, p *lsp.ReferenceParams) ([]lsp.Location, error) {
	log.Println("server.References()")
	if f := s.getFile(p.TextDocument.URI); f != nil {
		if tok := f.tokAt(p.Position); tok != nil {
			if s := tok.Text(f.res.Lines); s != "" {
				if id, ok := f.res.Identifiers[s]; ok {
					locs := make([]lsp.Location, len(id.References))
					for i, r := range id.References {
						locs[i] = lsp.Location{
							URI:   p.TextDocument.URI,
							Range: rangeToLSP(r.Range),
						}
					}
					return locs, nil
				}
			}
		}
	}
	return nil, nil
}
func (s *server) DocumentHighlight(ctx context.Context, p *lsp.DocumentHighlightParams) ([]lsp.DocumentHighlight, error) {
	log.Println("server.DocumentHighlight()")
	return nil, nil
}
func (s *server) DocumentSymbol(ctx context.Context, p *lsp.DocumentSymbolParams) ([]lsp.DocumentSymbol, error) {
	log.Println("server.DocumentSymbol()")
	return nil, nil
}
func (s *server) CodeAction(ctx context.Context, p *lsp.CodeActionParams) ([]lsp.CodeAction, error) {
	log.Println("server.CodeAction()")
	return nil, nil
}
func (s *server) Symbol(ctx context.Context, p *lsp.WorkspaceSymbolParams) ([]lsp.SymbolInformation, error) {
	log.Println("server.Symbol()")
	return nil, nil
}
func (s *server) CodeLens(ctx context.Context, p *lsp.CodeLensParams) ([]lsp.CodeLens, error) {
	log.Println("server.CodeLens()")
	return nil, nil
}
func (s *server) ResolveCodeLens(ctx context.Context, p *lsp.CodeLens) (*lsp.CodeLens, error) {
	log.Println("server.ResolveCodeLens()")
	return nil, nil
}
func (s *server) DocumentLink(ctx context.Context, p *lsp.DocumentLinkParams) ([]lsp.DocumentLink, error) {
	log.Println("server.DocumentLink()")
	return nil, nil
}
func (s *server) ResolveDocumentLink(ctx context.Context, p *lsp.DocumentLink) (*lsp.DocumentLink, error) {
	log.Println("server.ResolveDocumentLink()")
	return nil, nil
}
func (s *server) Formatting(ctx context.Context, p *lsp.DocumentFormattingParams) ([]lsp.TextEdit, error) {
	log.Println("server.Formatting()")
	if f := s.getFile(p.TextDocument.URI); f != nil {
		// Start by measuring the distance from the start of each line to the
		// first opcode on that line.
		lineInstOffsets, maxInstOffset, instOffset, curOffset := []int{}, 0, 0, -1
		for _, t := range f.res.Tokens {
			curOffset++ // whitespace between tokens
			switch t.Type {
			case parser.Ident:
				if _, isInst := schema.Opcodes[t.Text(f.res.Lines)]; isInst && instOffset == 0 {
					instOffset = curOffset
					continue
				}
			case parser.Newline:
				lineInstOffsets = append(lineInstOffsets, instOffset)
				if instOffset > maxInstOffset {
					maxInstOffset = instOffset
				}
				curOffset, instOffset = -1, 0
			default:
				curOffset += utf8.RuneCountInString(t.Text(f.res.Lines))
			}
		}
		lineInstOffsets = append(lineInstOffsets, instOffset)

		// Now rewrite each of the lines, adding padding at the start of the
		// line for alignment.
		sb, newline := strings.Builder{}, true
		for _, t := range f.res.Tokens {
			if newline {
				newline = false
				indent := maxInstOffset - lineInstOffsets[0]
				lineInstOffsets = lineInstOffsets[1:]
				switch t.Type {
				case parser.Newline, parser.Comment:
				default:
					for s := 0; s < indent; s++ {
						sb.WriteRune(' ')
					}
				}
			} else if t.Type != parser.Newline {
				sb.WriteString(" ")
			}

			sb.WriteString(t.Text(f.res.Lines))
			if t.Type == parser.Newline {
				newline = true
			}
		}

		formatted := sb.String()

		// Every good file ends with a single new line.
		formatted = strings.TrimRight(formatted, "\n") + "\n"

		return []lsp.TextEdit{
			{
				Range:   rangeToLSP(f.fullRange),
				NewText: formatted,
			},
		}, nil
	}
	return nil, nil
}
func (s *server) RangeFormatting(ctx context.Context, p *lsp.DocumentRangeFormattingParams) ([]lsp.TextEdit, error) {
	log.Println("server.RangeFormatting()")
	return nil, nil
}
func (s *server) OnTypeFormatting(ctx context.Context, p *lsp.DocumentOnTypeFormattingParams) ([]lsp.TextEdit, error) {
	log.Println("server.OnTypeFormatting()")
	return nil, nil
}
func (s *server) Rename(ctx context.Context, p *lsp.RenameParams) (*lsp.WorkspaceEdit, error) {
	log.Println("server.Rename()")
	if f := s.getFile(p.TextDocument.URI); f != nil {
		if tok := f.tokAt(p.Position); tok != nil {
			if s := tok.Text(f.res.Lines); s != "" {
				if id, ok := f.res.Identifiers[s]; ok {
					changes := make([]lsp.TextEdit, len(id.References))
					for i, r := range id.References {
						changes[i].Range = rangeToLSP(r.Range)
						changes[i].NewText = p.NewName
					}
					m := map[string][]lsp.TextEdit{}
					m[p.TextDocument.URI] = changes
					return &lsp.WorkspaceEdit{Changes: &m}, nil
				}
			}
		}
	}
	return nil, nil
}
func (s *server) PrepareRename(ctx context.Context, p *lsp.PrepareRenameParams) (*lsp.Range, error) {
	log.Println("server.PrepareRename()")
	return nil, nil
}
func (s *server) ExecuteCommand(ctx context.Context, p *lsp.ExecuteCommandParams) (interface{}, error) {
	log.Println("server.ExecuteCommand()")
	return nil, nil
}

func (s *server) processFile(ctx context.Context, uri, source string) error {
	log.Println("server.DidOpen()")
	res, err := parser.Parse(source)
	if err != nil {
		return err
	}
	fullRange := parser.Range{
		Start: parser.Position{Line: 1, Column: 1},
		End:   parser.Position{Line: len(res.Lines), Column: utf8.RuneCountInString(res.Lines[len(res.Lines)-1]) + 1},
	}

	s.filesMutex.Lock()
	s.files[uri] = &file{
		fullRange: fullRange,
		res:       res,
	}
	s.filesMutex.Unlock()

	dp := lsp.PublishDiagnosticsParams{URI: uri, Diagnostics: make([]lsp.Diagnostic, len(res.Diagnostics))}
	for i, d := range res.Diagnostics {
		dp.Diagnostics[i] = diagnosticToLSP(d)
	}
	s.client.PublishDiagnostics(ctx, &dp)
	return nil
}

func (s *server) getFile(uri string) *file {
	s.filesMutex.Lock()
	defer s.filesMutex.Unlock()
	return s.files[uri]
}

func diagnosticToLSP(d parser.Diagnostic) lsp.Diagnostic {
	return lsp.Diagnostic{
		Range:    rangeToLSP(d.Range),
		Severity: severityToLSP(d.Severity),
		Message:  d.Message,
	}
}

func severityToLSP(s parser.Severity) lsp.DiagnosticSeverity {
	switch s {
	case parser.SeverityError:
		return lsp.SeverityError
	case parser.SeverityWarning:
		return lsp.SeverityWarning
	case parser.SeverityInformation:
		return lsp.SeverityInformation
	case parser.SeverityHint:
		return lsp.SeverityHint
	default:
		log.Panicf("Invalid severity '%d'", int(s))
		return lsp.SeverityError
	}
}

func rangeToLSP(r parser.Range) lsp.Range {
	return lsp.Range{
		Start: positionToLSP(r.Start),
		End:   positionToLSP(r.End),
	}
}

func positionToLSP(r parser.Position) lsp.Position {
	return lsp.Position{
		Line:      float64(r.Line - 1),
		Character: float64(r.Column - 1),
	}
}
