// Copyright 2018 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 lsp

import (
	"context"
	"go/token"

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

// fromProtocolURI converts a protocol.DocumentURI to a source.URI.
// TODO(rstambler): Add logic here to support Windows.
func fromProtocolURI(uri protocol.DocumentURI) source.URI {
	return source.URI(uri)
}

// fromProtocolLocation converts from a protocol location to a source range.
// It will return an error if the file of the location was not valid.
// It uses fromProtocolRange to convert the start and end positions.
func fromProtocolLocation(ctx context.Context, v *cache.View, loc protocol.Location) (source.Range, error) {
	f, err := v.GetFile(ctx, fromProtocolURI(loc.URI))
	if err != nil {
		return source.Range{}, err
	}
	tok, err := f.GetToken()
	if err != nil {
		return source.Range{}, err
	}
	return fromProtocolRange(tok, loc.Range), nil
}

// toProtocolLocation converts from a source range back to a protocol location.
func toProtocolLocation(fset *token.FileSet, r source.Range) protocol.Location {
	tok := fset.File(r.Start)
	uri := source.ToURI(tok.Name())
	return protocol.Location{
		URI:   protocol.DocumentURI(uri),
		Range: toProtocolRange(tok, r),
	}
}

// fromProtocolRange converts a protocol range to a source range.
// It uses fromProtocolPosition to convert the start and end positions, which
// requires the token file the positions belongs to.
func fromProtocolRange(f *token.File, r protocol.Range) source.Range {
	start := fromProtocolPosition(f, r.Start)
	var end token.Pos
	switch {
	case r.End == r.Start:
		end = start
	case r.End.Line < 0:
		end = token.NoPos
	default:
		end = fromProtocolPosition(f, r.End)
	}
	return source.Range{
		Start: start,
		End:   end,
	}
}

// toProtocolRange converts from a source range back to a protocol range.
func toProtocolRange(f *token.File, r source.Range) protocol.Range {
	return protocol.Range{
		Start: toProtocolPosition(f, r.Start),
		End:   toProtocolPosition(f, r.End),
	}
}

// fromProtocolPosition converts a protocol position (0-based line and column
// number) to a token.Pos (byte offset value).
// It requires the token file the pos belongs to in order to do this.
func fromProtocolPosition(f *token.File, pos protocol.Position) token.Pos {
	line := lineStart(f, int(pos.Line)+1)
	return line + token.Pos(pos.Character) // TODO: this is wrong, bytes not characters
}

// toProtocolPosition converts from a token pos (byte offset) to a protocol
// position  (0-based line and column number)
// It requires the token file the pos belongs to in order to do this.
func toProtocolPosition(f *token.File, pos token.Pos) protocol.Position {
	if !pos.IsValid() {
		return protocol.Position{Line: -1.0, Character: -1.0}
	}
	p := f.Position(pos)
	return protocol.Position{
		Line:      float64(p.Line - 1),
		Character: float64(p.Column - 1),
	}
}

// fromTokenPosition converts a token.Position (1-based line and column
// number) to a token.Pos (byte offset value).
// It requires the token file the pos belongs to in order to do this.
func fromTokenPosition(f *token.File, pos token.Position) token.Pos {
	line := lineStart(f, pos.Line)
	return line + token.Pos(pos.Column-1) // TODO: this is wrong, bytes not characters
}

// this functionality was borrowed from the analysisutil package
func lineStart(f *token.File, line int) token.Pos {
	// Use binary search to find the start offset of this line.
	//
	// TODO(rstambler): eventually replace this function with the
	// simpler and more efficient (*go/token.File).LineStart, added
	// in go1.12.

	min := 0        // inclusive
	max := f.Size() // exclusive
	for {
		offset := (min + max) / 2
		pos := f.Pos(offset)
		posn := f.Position(pos)
		if posn.Line == line {
			return pos - (token.Pos(posn.Column) - 1)
		}

		if min+1 >= max {
			return token.NoPos
		}

		if posn.Line < line {
			min = offset
		} else {
			max = offset
		}
	}
}
