// Copyright 2019 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 cache

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"

	"golang.org/x/mod/modfile"
	"golang.org/x/tools/internal/event"
	"golang.org/x/tools/internal/lsp/debug/tag"
	"golang.org/x/tools/internal/lsp/protocol"
	"golang.org/x/tools/internal/lsp/source"
	"golang.org/x/tools/internal/memoize"
	"golang.org/x/tools/internal/span"
	errors "golang.org/x/xerrors"
)

const (
	SyntaxError = "syntax"
)

type parseModHandle struct {
	handle *memoize.Handle

	mod, sum source.FileHandle
}

type parseModData struct {
	memoize.NoCopy

	parsed *modfile.File
	m      *protocol.ColumnMapper

	// parseErrors refers to syntax errors found in the go.mod file.
	parseErrors []source.Error

	// err is any error encountered while parsing the file.
	err error
}

func (mh *parseModHandle) Mod() source.FileHandle {
	return mh.mod
}

func (mh *parseModHandle) Sum() source.FileHandle {
	return mh.sum
}

func (mh *parseModHandle) Parse(ctx context.Context, s source.Snapshot) (*modfile.File, *protocol.ColumnMapper, []source.Error, error) {
	v, err := mh.handle.Get(ctx, s.(*snapshot))
	if err != nil {
		return nil, nil, nil, err
	}
	data := v.(*parseModData)
	return data.parsed, data.m, data.parseErrors, data.err
}

func (s *snapshot) ParseModHandle(ctx context.Context, modFH source.FileHandle) (source.ParseModHandle, error) {
	if handle := s.getModHandle(modFH.URI()); handle != nil {
		return handle, nil
	}
	h := s.view.session.cache.store.Bind(modFH.Identity().String(), func(ctx context.Context, _ memoize.Arg) interface{} {
		_, done := event.Start(ctx, "cache.ParseModHandle", tag.URI.Of(modFH.URI()))
		defer done()

		contents, err := modFH.Read()
		if err != nil {
			return &parseModData{err: err}
		}
		m := &protocol.ColumnMapper{
			URI:       modFH.URI(),
			Converter: span.NewContentConverter(modFH.URI().Filename(), contents),
			Content:   contents,
		}
		parsed, err := modfile.Parse(modFH.URI().Filename(), contents, nil)
		if err != nil {
			parseErr, _ := extractModParseErrors(modFH.URI(), m, err, contents)
			var parseErrors []source.Error
			if parseErr != nil {
				parseErrors = append(parseErrors, *parseErr)
			}
			return &parseModData{
				parseErrors: parseErrors,
				err:         err,
			}
		}
		return &parseModData{
			parsed: parsed,
			m:      m,
		}
	})
	// Get the go.sum file, either from the snapshot or directly from the
	// cache. Avoid (*snapshot).GetFile here, as we don't want to add
	// nonexistent file handles to the snapshot if the file does not exist.
	sumURI := span.URIFromPath(sumFilename(modFH.URI()))
	sumFH := s.FindFile(sumURI)
	if sumFH == nil {
		fh, err := s.view.session.cache.getFile(ctx, sumURI)
		if err != nil && !os.IsNotExist(err) {
			return nil, err
		}
		if fh.err != nil && !os.IsNotExist(fh.err) {
			return nil, fh.err
		}
		// If the file doesn't exist, we can just keep the go.sum nil.
		if err != nil || fh.err != nil {
			sumFH = nil
		} else {
			sumFH = fh
		}
	}
	s.mu.Lock()
	defer s.mu.Unlock()
	s.parseModHandles[modFH.URI()] = &parseModHandle{
		handle: h,
		mod:    modFH,
		sum:    sumFH,
	}
	return s.parseModHandles[modFH.URI()], nil
}

func sumFilename(modURI span.URI) string {
	return modURI.Filename()[:len(modURI.Filename())-len("mod")] + "sum"
}

// extractModParseErrors processes the raw errors returned by modfile.Parse,
// extracting the filenames and line numbers that correspond to the errors.
func extractModParseErrors(uri span.URI, m *protocol.ColumnMapper, parseErr error, content []byte) (*source.Error, error) {
	re := regexp.MustCompile(`.*:([\d]+): (.+)`)
	matches := re.FindStringSubmatch(strings.TrimSpace(parseErr.Error()))
	if len(matches) < 3 {
		return nil, errors.Errorf("could not parse go.mod error message: %s", parseErr)
	}
	line, err := strconv.Atoi(matches[1])
	if err != nil {
		return nil, err
	}
	lines := strings.Split(string(content), "\n")
	if line > len(lines) {
		return nil, errors.Errorf("could not parse go.mod error message %q, line number %v out of range", content, line)
	}
	// The error returned from the modfile package only returns a line number,
	// so we assume that the diagnostic should be for the entire line.
	endOfLine := len(lines[line-1])
	sOffset, err := m.Converter.ToOffset(line, 0)
	if err != nil {
		return nil, err
	}
	eOffset, err := m.Converter.ToOffset(line, endOfLine)
	if err != nil {
		return nil, err
	}
	spn := span.New(uri, span.NewPoint(line, 0, sOffset), span.NewPoint(line, endOfLine, eOffset))
	rng, err := m.Range(spn)
	if err != nil {
		return nil, err
	}
	return &source.Error{
		Category: SyntaxError,
		Message:  matches[2],
		Range:    rng,
		URI:      uri,
	}, nil
}

// modKey is uniquely identifies cached data for `go mod why` or dependencies
// to upgrade.
type modKey struct {
	sessionID, cfg, mod, view string
	verb                      modAction
}

type modAction int

const (
	why modAction = iota
	upgrade
)

type modWhyHandle struct {
	handle *memoize.Handle
}

type modWhyData struct {
	// why keeps track of the `go mod why` results for each require statement
	// in the go.mod file.
	why map[string]string

	err error
}

func (mwh *modWhyHandle) Why(ctx context.Context, s source.Snapshot) (map[string]string, error) {
	v, err := mwh.handle.Get(ctx, s.(*snapshot))
	if err != nil {
		return nil, err
	}
	data := v.(*modWhyData)
	return data.why, data.err
}

func (s *snapshot) ModWhyHandle(ctx context.Context) (source.ModWhyHandle, error) {
	if err := s.awaitLoaded(ctx); err != nil {
		return nil, err
	}
	fh, err := s.GetFile(ctx, s.view.modURI)
	if err != nil {
		return nil, err
	}
	cfg := s.config(ctx)
	key := modKey{
		sessionID: s.view.session.id,
		cfg:       hashConfig(s.config(ctx)),
		mod:       fh.Identity().String(),
		view:      s.view.root.Filename(),
		verb:      why,
	}
	h := s.view.session.cache.store.Bind(key, func(ctx context.Context, arg memoize.Arg) interface{} {
		ctx, done := event.Start(ctx, "cache.ModWhyHandle", tag.URI.Of(fh.URI()))
		defer done()

		snapshot := arg.(*snapshot)

		pmh, err := snapshot.ParseModHandle(ctx, fh)
		if err != nil {
			return &modWhyData{err: err}
		}

		parsed, _, _, err := pmh.Parse(ctx, snapshot)
		if err != nil {
			return &modWhyData{err: err}
		}
		// No requires to explain.
		if len(parsed.Require) == 0 {
			return &modWhyData{}
		}
		// Run `go mod why` on all the dependencies.
		args := []string{"why", "-m"}
		for _, req := range parsed.Require {
			args = append(args, req.Mod.Path)
		}
		_, stdout, err := runGoCommand(ctx, cfg, pmh, snapshot.view.tmpMod, "mod", args)
		if err != nil {
			return &modWhyData{err: err}
		}
		whyList := strings.Split(stdout.String(), "\n\n")
		if len(whyList) != len(parsed.Require) {
			return &modWhyData{
				err: fmt.Errorf("mismatched number of results: got %v, want %v", len(whyList), len(parsed.Require)),
			}
		}
		why := make(map[string]string, len(parsed.Require))
		for i, req := range parsed.Require {
			why[req.Mod.Path] = whyList[i]
		}
		return &modWhyData{why: why}
	})
	s.mu.Lock()
	defer s.mu.Unlock()
	s.modWhyHandle = &modWhyHandle{
		handle: h,
	}
	return s.modWhyHandle, nil
}

type modUpgradeHandle struct {
	handle *memoize.Handle
}

type modUpgradeData struct {
	// upgrades maps modules to their latest versions.
	upgrades map[string]string

	err error
}

func (muh *modUpgradeHandle) Upgrades(ctx context.Context, s source.Snapshot) (map[string]string, error) {
	v, err := muh.handle.Get(ctx, s.(*snapshot))
	if v == nil {
		return nil, err
	}
	data := v.(*modUpgradeData)
	return data.upgrades, data.err
}

func (s *snapshot) ModUpgradeHandle(ctx context.Context) (source.ModUpgradeHandle, error) {
	if err := s.awaitLoaded(ctx); err != nil {
		return nil, err
	}
	fh, err := s.GetFile(ctx, s.view.modURI)
	if err != nil {
		return nil, err
	}
	cfg := s.config(ctx)
	key := modKey{
		sessionID: s.view.session.id,
		cfg:       hashConfig(cfg),
		mod:       fh.Identity().String(),
		view:      s.view.root.Filename(),
		verb:      upgrade,
	}
	h := s.view.session.cache.store.Bind(key, func(ctx context.Context, arg memoize.Arg) interface{} {
		ctx, done := event.Start(ctx, "cache.ModUpgradeHandle", tag.URI.Of(fh.URI()))
		defer done()

		snapshot := arg.(*snapshot)

		pmh, err := s.ParseModHandle(ctx, fh)
		if err != nil {
			return &modUpgradeData{err: err}
		}

		parsed, _, _, err := pmh.Parse(ctx, snapshot)
		if err != nil {
			return &modUpgradeData{err: err}
		}
		// No requires to upgrade.
		if len(parsed.Require) == 0 {
			return &modUpgradeData{}
		}
		// Run "go list -mod readonly -u -m all" to be able to see which deps can be
		// upgraded without modifying mod file.
		args := []string{"-u", "-m", "all"}
		if !snapshot.view.tmpMod || containsVendor(pmh.Mod().URI()) {
			// Use -mod=readonly if the module contains a vendor directory
			// (see golang/go#38711).
			args = append([]string{"-mod", "readonly"}, args...)
		}
		_, stdout, err := runGoCommand(ctx, cfg, pmh, snapshot.view.tmpMod, "list", args)
		if err != nil {
			return &modUpgradeData{err: err}
		}
		upgradesList := strings.Split(stdout.String(), "\n")
		if len(upgradesList) <= 1 {
			return nil
		}
		upgrades := make(map[string]string)
		for _, upgrade := range upgradesList[1:] {
			// Example: "github.com/x/tools v1.1.0 [v1.2.0]"
			info := strings.Split(upgrade, " ")
			if len(info) != 3 {
				continue
			}
			dep, version := info[0], info[2]

			// Make sure that the format matches our expectation.
			if len(version) < 2 {
				continue
			}
			if version[0] != '[' || version[len(version)-1] != ']' {
				continue
			}
			latest := version[1 : len(version)-1] // remove the "[" and "]"
			upgrades[dep] = latest
		}
		return &modUpgradeData{
			upgrades: upgrades,
		}
	})
	s.mu.Lock()
	defer s.mu.Unlock()
	s.modUpgradeHandle = &modUpgradeHandle{
		handle: h,
	}
	return s.modUpgradeHandle, nil
}

// containsVendor reports whether the module has a vendor folder.
func containsVendor(modURI span.URI) bool {
	dir := filepath.Dir(modURI.Filename())
	f, err := os.Stat(filepath.Join(dir, "vendor"))
	if err != nil {
		return false
	}
	return f.IsDir()
}
