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

// 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:      float64(p.Line),
		Character: float64(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
}
