// Copyright 2023 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 bench

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"sync"
	"testing"
	"time"

	"golang.org/x/tools/gopls/internal/lsp/fake"
	. "golang.org/x/tools/gopls/internal/lsp/regtest"
)

// repos holds shared repositories for use in benchmarks.
//
// These repos were selected to represent a variety of different types of
// codebases.
var repos = map[string]*repo{
	// Used by x/benchmarks; large.
	"istio": {
		name:   "istio",
		url:    "https://github.com/istio/istio",
		commit: "1.17.0",
	},

	// Kubernetes is a large repo with many dependencies, and in the past has
	// been about as large a repo as gopls could handle.
	"kubernetes": {
		name:   "kubernetes",
		url:    "https://github.com/kubernetes/kubernetes",
		commit: "v1.24.0",
	},

	// A large, industrial application.
	"kuma": {
		name:   "kuma",
		url:    "https://github.com/kumahq/kuma",
		commit: "2.1.1",
	},

	// x/pkgsite is familiar and represents a common use case (a webserver). It
	// also has a number of static non-go files and template files.
	"pkgsite": {
		name:   "pkgsite",
		url:    "https://go.googlesource.com/pkgsite",
		commit: "81f6f8d4175ad0bf6feaa03543cc433f8b04b19b",
		short:  true,
	},

	// A tiny self-contained project.
	"starlark": {
		name:   "starlark",
		url:    "https://github.com/google/starlark-go",
		commit: "3f75dec8e4039385901a30981e3703470d77e027",
		short:  true,
	},

	// The current repository, which is medium-small and has very few dependencies.
	"tools": {
		name:   "tools",
		url:    "https://go.googlesource.com/tools",
		commit: "gopls/v0.9.0",
		short:  true,
	},
}

// getRepo gets the requested repo, and skips the test if -short is set and
// repo is not configured as a short repo.
func getRepo(tb testing.TB, name string) *repo {
	tb.Helper()
	repo := repos[name]
	if repo == nil {
		tb.Fatalf("repo %s does not exist", name)
	}
	if !repo.short && testing.Short() {
		tb.Skipf("large repo %s does not run whith -short", repo.name)
	}
	return repo
}

// A repo represents a working directory for a repository checked out at a
// specific commit.
//
// Repos are used for sharing state across benchmarks that operate on the same
// codebase.
type repo struct {
	// static configuration
	name   string // must be unique, used for subdirectory
	url    string // repo url
	commit string // full commit hash or tag
	short  bool   // whether this repo runs with -short

	dirOnce sync.Once
	dir     string // directory contaning source code checked out to url@commit

	// shared editor state
	editorOnce sync.Once
	editor     *fake.Editor
	sandbox    *fake.Sandbox
	awaiter    *Awaiter
}

// getDir returns directory containing repo source code, creating it if
// necessary. It is safe for concurrent use.
func (r *repo) getDir() string {
	r.dirOnce.Do(func() {
		r.dir = filepath.Join(getTempDir(), r.name)
		log.Printf("cloning %s@%s into %s", r.url, r.commit, r.dir)
		if err := shallowClone(r.dir, r.url, r.commit); err != nil {
			log.Fatal(err)
		}
	})
	return r.dir
}

// sharedEnv returns a shared benchmark environment. It is safe for concurrent
// use.
//
// Every call to sharedEnv uses the same editor and sandbox, as a means to
// avoid reinitializing the editor for large repos. Calling repo.Close cleans
// up the shared environment.
//
// Repos in the package-local Repos var are closed at the end of the test main
// function.
func (r *repo) sharedEnv(tb testing.TB) *Env {
	r.editorOnce.Do(func() {
		dir := r.getDir()

		start := time.Now()
		log.Printf("starting initial workspace load for %s", r.name)
		ts, err := newGoplsServer(r.name)
		if err != nil {
			log.Fatal(err)
		}
		r.sandbox, r.editor, r.awaiter, err = connectEditor(dir, fake.EditorConfig{}, ts)
		if err != nil {
			log.Fatalf("connecting editor: %v", err)
		}

		if err := r.awaiter.Await(context.Background(), InitialWorkspaceLoad); err != nil {
			log.Fatal(err)
		}
		log.Printf("initial workspace load (cold) for %s took %v", r.name, time.Since(start))
	})

	return &Env{
		T:       tb,
		Ctx:     context.Background(),
		Editor:  r.editor,
		Sandbox: r.sandbox,
		Awaiter: r.awaiter,
	}
}

// newEnv returns a new Env connected to a new gopls process communicating
// over stdin/stdout. It is safe for concurrent use.
//
// It is the caller's responsibility to call Close on the resulting Env when it
// is no longer needed.
func (r *repo) newEnv(tb testing.TB, name string, config fake.EditorConfig) *Env {
	dir := r.getDir()

	ts, err := newGoplsServer(name)
	if err != nil {
		tb.Fatal(err)
	}
	sandbox, editor, awaiter, err := connectEditor(dir, config, ts)
	if err != nil {
		log.Fatalf("connecting editor: %v", err)
	}

	return &Env{
		T:       tb,
		Ctx:     context.Background(),
		Editor:  editor,
		Sandbox: sandbox,
		Awaiter: awaiter,
	}
}

// Close cleans up shared state referenced by the repo.
func (r *repo) Close() error {
	var errBuf bytes.Buffer
	if r.editor != nil {
		if err := r.editor.Close(context.Background()); err != nil {
			fmt.Fprintf(&errBuf, "closing editor: %v", err)
		}
	}
	if r.sandbox != nil {
		if err := r.sandbox.Close(); err != nil {
			fmt.Fprintf(&errBuf, "closing sandbox: %v", err)
		}
	}
	if r.dir != "" {
		if err := os.RemoveAll(r.dir); err != nil {
			fmt.Fprintf(&errBuf, "cleaning dir: %v", err)
		}
	}
	if errBuf.Len() > 0 {
		return errors.New(errBuf.String())
	}
	return nil
}

// cleanup cleans up state that is shared across benchmark functions.
func cleanup() error {
	var errBuf bytes.Buffer
	for _, repo := range repos {
		if err := repo.Close(); err != nil {
			fmt.Fprintf(&errBuf, "closing %q: %v", repo.name, err)
		}
	}
	if tempDir != "" {
		if err := os.RemoveAll(tempDir); err != nil {
			fmt.Fprintf(&errBuf, "cleaning tempDir: %v", err)
		}
	}
	if errBuf.Len() > 0 {
		return errors.New(errBuf.String())
	}
	return nil
}
