// Copyright 2020 The Fuchsia 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 state

import (
	"fmt"
	"net/url"
	"strings"
)

// A FileID is a path to a file open in the client editor.
//
// We never assume the "saved-ness" of a file, and maintain all files that are
// open in the editor in memory. Therefore this path does not necessarily
// correspond to an absolute filepath; it's just used as an ID to access the
// in-memory file.
type FileID string

// FileSystem manages file synchronization between client and server.
// `files` is an in-memory mapping of URI to file contents of the currently open
// files on the client.
type FileSystem struct {
	// TODO: should this be a map[FileID][]byte instead?

	// `files` is stored as a map of FileIDs to files that are split by line
	// (but retaining their '\n' characters).
	// This speeds up the common operation of searching for a symbol at a given
	// (line, column) in the file as the file is indexed by line.
	files map[FileID][]string

	// TODO: RWLock for safe concurrency
}

// Range represents a span of text in a source file.
type Range struct {
	Start Position
	End   Position
}

// Position represents the location of one character in a source file.
// Both are zero-indexed, i.e. lines start at 0 and the first character of a
// line is at index 0.
type Position struct {
	Line      int
	Character int
}

// Location represents a range in a particular file.
type Location struct {
	FileID FileID
	Range  Range
}

// Change represents a single diff in a source file.
// Range is the range that is being changed. RangeLength is the length of the
// replacement text (0 if the range is being deleted). Text is the text to
// insert in the source at that range.
type Change struct {
	Range      Range
	NewContent string
}

// NewFileSystem returns an initialized empty FileSystem.
func NewFileSystem() *FileSystem {
	return &FileSystem{
		files: make(map[FileID][]string),
	}
}

// File is a read-only accessor for the in-memory file with ID `path`.
func (fs *FileSystem) File(path FileID) (string, error) {
	if lines, ok := fs.files[path]; ok {
		return strings.Join(lines, ""), nil
	}
	return "", fmt.Errorf("file `%s` not in memory", path)
}

// NFiles returns the number of in-memory files.
func (fs *FileSystem) NFiles() int {
	return len(fs.files)
}

// NewFile copies `text` into the FileSystem's in-memory file system ("opening"
// the file), indexed by the FileID `path`.
func (fs *FileSystem) NewFile(path FileID, text string) {
	fs.files[path] = strings.SplitAfter(text, "\n")
}

// DeleteFile deletes the FileSystem's in-memory representation of the file
// indexed by `path`.
func (fs *FileSystem) DeleteFile(path FileID) {
	delete(fs.files, path)
}

// ApplyChanges applies the specified changes to the relevant in-memory file.
func (fs *FileSystem) ApplyChanges(path FileID, changes []Change) error {
	for _, change := range changes {
		start, err := OffsetInFile(fs.files[path], change.Range.Start)
		if err != nil {
			return err
		}
		end, err := OffsetInFile(fs.files[path], change.Range.End)
		if err != nil {
			return err
		}

		file := strings.Join(fs.files[path], "")

		// Copy file over to new buffer with inserted text change
		var newFile strings.Builder
		newFile.WriteString(file[:start])
		newFile.WriteString(change.NewContent)
		newFile.WriteString(file[end:])
		fs.files[path] = strings.SplitAfter(newFile.String(), "\n")
	}
	return nil
}

// OffsetInFile converts a Position (line, character) to a rune offset in
// `contents`.
func OffsetInFile(lines []string, pos Position) (uint, error) {
	var offset uint
	for line, l := range lines {
		for col := range l {
			if line == pos.Line && col == pos.Character {
				return offset, nil
			}
			offset++
		}
	}
	// Check if pos is pointing at the end of the file
	lastLine := len(lines) - 1
	if pos.Line == lastLine && pos.Character == len(lines[lastLine]) {
		return offset, nil
	}
	return 0, fmt.Errorf(
		"position %#v was out of bounds in file with %d lines, %d total chars",
		pos,
		len(lines),
		offset,
	)
}

// FileIDToPath converts a FileID, which is in the form of a file schema URI
// ("file:///"), to an absolute path.
func FileIDToPath(fileID FileID) (string, error) {
	fileURI, err := url.Parse(string(fileID))
	if err != nil {
		return "", fmt.Errorf("could not parse FileID: %s", err)
	}
	return fileURI.Path, nil
}
