// Copyright 2020 The Go 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 fake

import (
	"fmt"
	"sort"
	"strings"

	"golang.org/x/tools/internal/lsp/protocol"
)

// Pos represents a position in a text buffer. Both Line and Column are
// 0-indexed.
type Pos struct {
	Line, Column int
}

func (p Pos) String() string {
	return fmt.Sprintf("%v:%v", p.Line, p.Column)
}

// Range corresponds to protocol.Range, but uses the editor friend Pos
// instead of UTF-16 oriented protocol.Position
type Range struct {
	Start Pos
	End   Pos
}

func (p Pos) ToProtocolPosition() protocol.Position {
	return protocol.Position{
		Line:      uint32(p.Line),
		Character: uint32(p.Column),
	}
}

func fromProtocolPosition(pos protocol.Position) Pos {
	return Pos{
		Line:   int(pos.Line),
		Column: int(pos.Character),
	}
}

// Edit represents a single (contiguous) buffer edit.
type Edit struct {
	Start, End Pos
	Text       string
}

// Location is the editor friendly equivalent of protocol.Location
type Location struct {
	Path  string
	Range Range
}

// SymbolInformation is an editor friendly version of
// protocol.SymbolInformation, with location information transformed to byte
// offsets. Field names correspond to the protocol type.
type SymbolInformation struct {
	Name     string
	Kind     protocol.SymbolKind
	Location Location
}

// NewEdit creates an edit replacing all content between
// (startLine, startColumn) and (endLine, endColumn) with text.
func NewEdit(startLine, startColumn, endLine, endColumn int, text string) Edit {
	return Edit{
		Start: Pos{Line: startLine, Column: startColumn},
		End:   Pos{Line: endLine, Column: endColumn},
		Text:  text,
	}
}

func (e Edit) toProtocolChangeEvent() protocol.TextDocumentContentChangeEvent {
	return protocol.TextDocumentContentChangeEvent{
		Range: &protocol.Range{
			Start: e.Start.ToProtocolPosition(),
			End:   e.End.ToProtocolPosition(),
		},
		Text: e.Text,
	}
}

func fromProtocolTextEdit(textEdit protocol.TextEdit) Edit {
	return Edit{
		Start: fromProtocolPosition(textEdit.Range.Start),
		End:   fromProtocolPosition(textEdit.Range.End),
		Text:  textEdit.NewText,
	}
}

// inText reports whether p is a valid position in the text buffer.
func inText(p Pos, content []string) bool {
	if p.Line < 0 || p.Line >= len(content) {
		return false
	}
	// Note the strict right bound: the column indexes character _separators_,
	// not characters.
	if p.Column < 0 || p.Column > len([]rune(content[p.Line])) {
		return false
	}
	return true
}

// editContent implements a simplistic, inefficient algorithm for applying text
// edits to our buffer representation. It returns an error if the edit is
// invalid for the current content.
func editContent(content []string, edits []Edit) ([]string, error) {
	newEdits := make([]Edit, len(edits))
	copy(newEdits, edits)
	sort.Slice(newEdits, func(i, j int) bool {
		if newEdits[i].Start.Line < newEdits[j].Start.Line {
			return true
		}
		if newEdits[i].Start.Line > newEdits[j].Start.Line {
			return false
		}
		return newEdits[i].Start.Column < newEdits[j].Start.Column
	})

	// Validate edits.
	for _, edit := range newEdits {
		if edit.End.Line < edit.Start.Line || (edit.End.Line == edit.Start.Line && edit.End.Column < edit.Start.Column) {
			return nil, fmt.Errorf("invalid edit: end %v before start %v", edit.End, edit.Start)
		}
		if !inText(edit.Start, content) {
			return nil, fmt.Errorf("start position %v is out of bounds", edit.Start)
		}
		if !inText(edit.End, content) {
			return nil, fmt.Errorf("end position %v is out of bounds", edit.End)
		}
	}

	var (
		b            strings.Builder
		line, column int
	)
	advance := func(toLine, toColumn int) {
		for ; line < toLine; line++ {
			b.WriteString(string([]rune(content[line])[column:]) + "\n")
			column = 0
		}
		b.WriteString(string([]rune(content[line])[column:toColumn]))
		column = toColumn
	}
	for _, edit := range newEdits {
		advance(edit.Start.Line, edit.Start.Column)
		b.WriteString(edit.Text)
		line = edit.End.Line
		column = edit.End.Column
	}
	advance(len(content)-1, len([]rune(content[len(content)-1])))
	return strings.Split(b.String(), "\n"), nil
}
