// 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"
	"io/ioutil"
	"log"
	"os"
	"path"
	"sort"
	"strings"
	"sync"
	"unicode/utf8"

	"./parser"
	"./schema"

	"./lsp/jsonrpc2"
	lsp "./lsp/protocol"
)

// 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() {
	// 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)
	} else {
		log.SetOutput(ioutil.Discard)
	}

	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,
		},
	}
	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 (s *server) Completion(ctx context.Context, p *lsp.CompletionParams) (*lsp.CompletionList, error) {
	log.Println("server.Completion()")
	return nil, 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(fmt.Sprintf("```\n%v\n```", v.Opcode.Opname))
		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
			}
		}

		// Every good file ends with a new line.
		sb.WriteString("\n")

		return []lsp.TextEdit{
			lsp.TextEdit{
				Range:   rangeToLSP(f.fullRange),
				NewText: sb.String(),
			},
		}, 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),
	}
}
