// 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 modcmd

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io/fs"
	"os"
	"runtime"

	"cmd/go/internal/base"
	"cmd/go/internal/modfetch"
	"cmd/go/internal/modload"

	"golang.org/x/mod/module"
	"golang.org/x/mod/sumdb/dirhash"
)

var cmdVerify = &base.Command{
	UsageLine: "go mod verify",
	Short:     "verify dependencies have expected content",
	Long: `
Verify checks that the dependencies of the current module,
which are stored in a local downloaded source cache, have not been
modified since being downloaded. If all the modules are unmodified,
verify prints "all modules verified." Otherwise it reports which
modules have been changed and causes 'go mod' to exit with a
non-zero status.

See https://golang.org/ref/mod#go-mod-verify for more about 'go mod verify'.
	`,
	Run: runVerify,
}

func init() {
	base.AddModCommonFlags(&cmdVerify.Flag)
	base.AddWorkfileFlag(&cmdVerify.Flag)
}

func runVerify(ctx context.Context, cmd *base.Command, args []string) {
	modload.InitWorkfile()

	if len(args) != 0 {
		// NOTE(rsc): Could take a module pattern.
		base.Fatalf("go: verify takes no arguments")
	}
	modload.ForceUseModules = true
	modload.RootMode = modload.NeedRoot

	// Only verify up to GOMAXPROCS zips at once.
	type token struct{}
	sem := make(chan token, runtime.GOMAXPROCS(0))

	// Use a slice of result channels, so that the output is deterministic.
	const defaultGoVersion = ""
	mods := modload.LoadModGraph(ctx, defaultGoVersion).BuildList()[1:]
	errsChans := make([]<-chan []error, len(mods))

	for i, mod := range mods {
		sem <- token{}
		errsc := make(chan []error, 1)
		errsChans[i] = errsc
		mod := mod // use a copy to avoid data races
		go func() {
			errsc <- verifyMod(mod)
			<-sem
		}()
	}

	ok := true
	for _, errsc := range errsChans {
		errs := <-errsc
		for _, err := range errs {
			base.Errorf("%s", err)
			ok = false
		}
	}
	if ok {
		fmt.Printf("all modules verified\n")
	}
}

func verifyMod(mod module.Version) []error {
	var errs []error
	zip, zipErr := modfetch.CachePath(mod, "zip")
	if zipErr == nil {
		_, zipErr = os.Stat(zip)
	}
	dir, dirErr := modfetch.DownloadDir(mod)
	data, err := os.ReadFile(zip + "hash")
	if err != nil {
		if zipErr != nil && errors.Is(zipErr, fs.ErrNotExist) &&
			dirErr != nil && errors.Is(dirErr, fs.ErrNotExist) {
			// Nothing downloaded yet. Nothing to verify.
			return nil
		}
		errs = append(errs, fmt.Errorf("%s %s: missing ziphash: %v", mod.Path, mod.Version, err))
		return errs
	}
	h := string(bytes.TrimSpace(data))

	if zipErr != nil && errors.Is(zipErr, fs.ErrNotExist) {
		// ok
	} else {
		hZ, err := dirhash.HashZip(zip, dirhash.DefaultHash)
		if err != nil {
			errs = append(errs, fmt.Errorf("%s %s: %v", mod.Path, mod.Version, err))
			return errs
		} else if hZ != h {
			errs = append(errs, fmt.Errorf("%s %s: zip has been modified (%v)", mod.Path, mod.Version, zip))
		}
	}
	if dirErr != nil && errors.Is(dirErr, fs.ErrNotExist) {
		// ok
	} else {
		hD, err := dirhash.HashDir(dir, mod.Path+"@"+mod.Version, dirhash.DefaultHash)
		if err != nil {

			errs = append(errs, fmt.Errorf("%s %s: %v", mod.Path, mod.Version, err))
			return errs
		}
		if hD != h {
			errs = append(errs, fmt.Errorf("%s %s: dir has been modified (%v)", mod.Path, mod.Version, dir))
		}
	}
	return errs
}
