// 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 (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"sync"

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

// FileEvent wraps the protocol.FileEvent so that it can be associated with a
// workspace-relative path.
type FileEvent struct {
	Path          string
	ProtocolEvent protocol.FileEvent
}

// The Workspace type represents a temporary workspace to use for editing Go
// files in tests.
type Workspace struct {
	name    string
	gopath  string
	workdir string

	watcherMu sync.Mutex
	watchers  []func(context.Context, []FileEvent)
}

// NewWorkspace creates a named workspace populated by the txtar-encoded
// content given by txt. It creates temporary directories for the workspace
// content and for GOPATH.
func NewWorkspace(name string, txt []byte) (_ *Workspace, err error) {
	w := &Workspace{name: name}
	defer func() {
		// Clean up if we fail at any point in this constructor.
		if err != nil {
			w.removeAll()
		}
	}()
	dir, err := ioutil.TempDir("", fmt.Sprintf("goplstest-ws-%s-", name))
	if err != nil {
		return nil, fmt.Errorf("creating temporary workdir: %v", err)
	}
	w.workdir = dir
	gopath, err := ioutil.TempDir("", fmt.Sprintf("goplstest-gopath-%s-", name))
	if err != nil {
		return nil, fmt.Errorf("creating temporary gopath: %v", err)
	}
	w.gopath = gopath
	archive := txtar.Parse(txt)
	for _, f := range archive.Files {
		if err := w.writeFileData(f.Name, f.Data); err != nil {
			return nil, err
		}
	}
	return w, nil
}

// RootURI returns the root URI for this workspace.
func (w *Workspace) RootURI() protocol.DocumentURI {
	return toURI(w.workdir)
}

// GOPATH returns the value that GOPATH should be set to for this workspace.
func (w *Workspace) GOPATH() string {
	return w.gopath
}

// AddWatcher registers the given func to be called on any file change.
func (w *Workspace) AddWatcher(watcher func(context.Context, []FileEvent)) {
	w.watcherMu.Lock()
	w.watchers = append(w.watchers, watcher)
	w.watcherMu.Unlock()
}

// filePath returns the absolute filesystem path to a the workspace-relative
// path.
func (w *Workspace) filePath(path string) string {
	fp := filepath.FromSlash(path)
	if filepath.IsAbs(fp) {
		return fp
	}
	return filepath.Join(w.workdir, filepath.FromSlash(path))
}

// URI returns the URI to a the workspace-relative path.
func (w *Workspace) URI(path string) protocol.DocumentURI {
	return toURI(w.filePath(path))
}

// URIToPath converts a uri to a workspace-relative path (or an absolute path,
// if the uri is outside of the workspace).
func (w *Workspace) URIToPath(uri protocol.DocumentURI) string {
	root := w.RootURI() + "/"
	if strings.HasPrefix(uri, root) {
		return strings.TrimPrefix(uri, root)
	}
	filename := span.NewURI(string(uri)).Filename()
	return filepath.ToSlash(filename)
}

func toURI(fp string) protocol.DocumentURI {
	return protocol.DocumentURI(span.FileURI(fp))
}

// ReadFile reads a text file specified by a workspace-relative path.
func (w *Workspace) ReadFile(path string) (string, error) {
	b, err := ioutil.ReadFile(w.filePath(path))
	if err != nil {
		return "", err
	}
	return string(b), nil
}

// RemoveFile removes a workspace-relative file path.
func (w *Workspace) RemoveFile(ctx context.Context, path string) error {
	fp := w.filePath(path)
	if err := os.Remove(fp); err != nil {
		return fmt.Errorf("removing %q: %v", path, err)
	}
	evts := []FileEvent{{
		Path: path,
		ProtocolEvent: protocol.FileEvent{
			URI:  w.URI(path),
			Type: protocol.Deleted,
		},
	}}
	w.sendEvents(ctx, evts)
	return nil
}

func (w *Workspace) sendEvents(ctx context.Context, evts []FileEvent) {
	w.watcherMu.Lock()
	watchers := make([]func(context.Context, []FileEvent), len(w.watchers))
	copy(watchers, w.watchers)
	w.watcherMu.Unlock()
	for _, w := range watchers {
		go w(ctx, evts)
	}
}

// WriteFile writes text file content to a workspace-relative path.
func (w *Workspace) WriteFile(ctx context.Context, path, content string) error {
	fp := w.filePath(path)
	_, err := os.Stat(fp)
	if err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("checking if %q exists: %v", path, err)
	}
	var changeType protocol.FileChangeType
	if os.IsNotExist(err) {
		changeType = protocol.Created
	} else {
		changeType = protocol.Changed
	}
	if err := w.writeFileData(path, []byte(content)); err != nil {
		return err
	}
	evts := []FileEvent{{
		Path: path,
		ProtocolEvent: protocol.FileEvent{
			URI:  w.URI(path),
			Type: changeType,
		},
	}}
	w.sendEvents(ctx, evts)
	return nil
}

func (w *Workspace) writeFileData(path string, data []byte) error {
	fp := w.filePath(path)
	if err := os.MkdirAll(filepath.Dir(fp), 0755); err != nil {
		return fmt.Errorf("creating nested directory: %v", err)
	}
	if err := ioutil.WriteFile(fp, data, 0644); err != nil {
		return fmt.Errorf("writing %q: %v", path, err)
	}
	return nil
}

func (w *Workspace) removeAll() error {
	var werr, perr error
	if w.workdir != "" {
		werr = os.RemoveAll(w.workdir)
	}
	if w.gopath != "" {
		perr = os.RemoveAll(w.gopath)
	}
	if werr != nil || perr != nil {
		return fmt.Errorf("error(s) cleaning workspace: removing workdir: %v; removing gopath: %v", werr, perr)
	}
	return nil
}

// Close removes all state associated with the workspace.
func (w *Workspace) Close() error {
	return w.removeAll()
}
