// 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 sample provides functionality for generating sample values of
// the types contained in the internal package.
package sample

import (
	"context"
	"fmt"
	"go/parser"
	"go/token"
	"math"
	"net/http"
	"path"
	"strings"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"github.com/google/licensecheck"
	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/godoc"
	"golang.org/x/pkgsite/internal/licenses"
	"golang.org/x/pkgsite/internal/source"
	"golang.org/x/pkgsite/internal/stdlib"
)

// These sample values can be used to construct test cases.
var (
	ModulePath                = "github.com/valid/module_name"
	RepositoryURL             = "https://github.com/valid/module_name"
	VersionString             = "v1.0.0"
	CommitTime                = NowTruncated()
	LicenseType               = "MIT"
	LicenseFilePath           = "LICENSE"
	NonRedistributableLicense = &licenses.License{
		Metadata: &licenses.Metadata{
			FilePath: "NONREDIST_LICENSE",
			Types:    []string{"UNKNOWN"},
		},
		Contents: []byte(`unknown`),
	}
	PackageName    = "foo"
	Suffix         = "foo"
	PackagePath    = path.Join(ModulePath, Suffix)
	V1Path         = PackagePath
	ReadmeFilePath = "README.md"
	ReadmeContents = "readme"
	GOOS           = internal.All
	GOARCH         = internal.All
	Doc            = Documentation(GOOS, GOARCH, DocContents)
	API            = []*internal.Symbol{
		Constant,
		Variable,
		Function,
		Type,
	}
	DocContents = `
		// Package p is a package.
		//
		//
		// Links
		//
		// - pkg.go.dev, https://pkg.go.dev
 		package p
		var V int
	`
	Constant = &internal.Symbol{
		SymbolMeta: internal.SymbolMeta{
			Name:     "Constant",
			Synopsis: "const Constant",
			Section:  internal.SymbolSectionConstants,
			Kind:     internal.SymbolKindConstant,
		},
		GOOS:   internal.All,
		GOARCH: internal.All,
	}
	Variable = &internal.Symbol{
		SymbolMeta: internal.SymbolMeta{
			Name:     "Variable",
			Synopsis: "var Variable",
			Section:  internal.SymbolSectionVariables,
			Kind:     internal.SymbolKindVariable,
		},
		GOOS:   internal.All,
		GOARCH: internal.All,
	}
	Function = &internal.Symbol{
		SymbolMeta: internal.SymbolMeta{
			Name:     "Function",
			Synopsis: "func Function() error",
			Section:  internal.SymbolSectionFunctions,
			Kind:     internal.SymbolKindFunction,
		},
		GOOS:   internal.All,
		GOARCH: internal.All,
	}
	FunctionNew = &internal.Symbol{
		SymbolMeta: internal.SymbolMeta{
			Name:       "New",
			Synopsis:   "func New() *Type",
			Section:    internal.SymbolSectionTypes,
			Kind:       internal.SymbolKindFunction,
			ParentName: "Type",
		},
		GOOS:   internal.All,
		GOARCH: internal.All,
	}
	Type = &internal.Symbol{
		SymbolMeta: internal.SymbolMeta{
			Name:     "Type",
			Synopsis: "type Type struct",
			Section:  internal.SymbolSectionTypes,
			Kind:     internal.SymbolKindType,
		},
		GOOS:   internal.All,
		GOARCH: internal.All,
		Children: []*internal.SymbolMeta{
			&FunctionNew.SymbolMeta,
			&Field,
			&Method,
		},
	}
	Field = internal.SymbolMeta{
		Name:       "Type.Field",
		Synopsis:   "field",
		Section:    internal.SymbolSectionTypes,
		Kind:       internal.SymbolKindField,
		ParentName: "Type",
	}
	Method = internal.SymbolMeta{
		Name:       "Type.Method",
		Synopsis:   "method",
		Section:    internal.SymbolSectionTypes,
		Kind:       internal.SymbolKindMethod,
		ParentName: "Type",
	}
)

// LicenseCmpOpts are options to use when comparing licenses with the cmp package.
var LicenseCmpOpts = []cmp.Option{
	cmp.Comparer(coveragePercentEqual),
	cmpopts.IgnoreFields(licensecheck.Match{}, "Start", "End"),
}

// coveragePercentEqual considers two floats the same if they are within 4
// percentage points, and both are on the same side of 90% (our threshold).
func coveragePercentEqual(a, b float64) bool {
	if (a >= 90) != (b >= 90) {
		return false
	}
	return math.Abs(a-b) <= 4
}

// NowTruncated returns time.Now() truncated to Microsecond precision.
//
// This makes it easier to work with timestamps in PostgreSQL, which have
// Microsecond precision:
//
//	https://www.postgresql.org/docs/9.1/datatype-datetime.html
func NowTruncated() time.Time {
	return time.Now().In(time.UTC).Truncate(time.Microsecond)
}

func DefaultModule() *internal.Module {
	fp := constructFullPath(ModulePath, Suffix)
	return AddPackage(Module(ModulePath, VersionString), UnitForPackage(fp, ModulePath, VersionString, path.Base(fp), true))
}

// Module creates a Module with the given path and version.
// The list of suffixes is used to create Units within the module.
func Module(modulePath, version string, suffixes ...string) *internal.Module {
	mi := ModuleInfo(modulePath, version)
	m := &internal.Module{
		ModuleInfo: *mi,
		Licenses:   Licenses(),
	}
	m.Units = []*internal.Unit{UnitForModuleRoot(mi)}
	for _, s := range suffixes {
		fp := constructFullPath(modulePath, s)
		lp := UnitForPackage(fp, modulePath, VersionString, path.Base(fp), m.IsRedistributable)
		if s != "" {
			AddPackage(m, lp)
		} else {
			u := UnitForPackage(lp.Path, modulePath, version, lp.Name, lp.IsRedistributable)
			m.Units[0].Documentation = u.Documentation
			m.Units[0].Name = u.Name
		}
	}
	if modulePath == stdlib.ModulePath {
		m.Units[0].Readme = nil
	}
	// Fill in license contents.
	for _, u := range m.Units {
		u.LicenseContents = m.Licenses
	}
	return m
}

func UnitForModuleRoot(m *internal.ModuleInfo) *internal.Unit {
	u := &internal.Unit{
		UnitMeta:        *UnitMeta(m.ModulePath, m.ModulePath, m.Version, "", m.IsRedistributable),
		LicenseContents: Licenses(),
	}
	u.Readme = &internal.Readme{
		Filepath: ReadmeFilePath,
		Contents: ReadmeContents,
	}
	return u
}

// UnitForPackage constructs a unit with the given module path and suffix.
//
// If modulePath is the standard library, the package path is the
// suffix, which must not be empty. Otherwise, the package path
// is the concatenation of modulePath and suffix.
//
// The package name is last component of the package path.
func UnitForPackage(path, modulePath, version, name string, isRedistributable bool) *internal.Unit {
	// Copy Doc because some tests modify it.
	doc := *Doc
	imps := Imports()
	return &internal.Unit{
		UnitMeta:        *UnitMeta(path, modulePath, version, name, isRedistributable),
		Documentation:   []*internal.Documentation{&doc},
		BuildContexts:   []internal.BuildContext{{GOOS: doc.GOOS, GOARCH: doc.GOARCH}},
		LicenseContents: Licenses(),
		Imports:         imps,
		NumImports:      len(imps),
	}
}

func AddPackage(m *internal.Module, pkg *internal.Unit) *internal.Module {
	if m.ModulePath != stdlib.ModulePath && !strings.HasPrefix(pkg.Path, m.ModulePath) {
		panic(fmt.Sprintf("package path %q not a prefix of module path %q",
			pkg.Path, m.ModulePath))
	}
	AddUnit(m, UnitForPackage(pkg.Path, m.ModulePath, m.Version, pkg.Name, pkg.IsRedistributable))
	minLen := len(m.ModulePath)
	if m.ModulePath == stdlib.ModulePath {
		minLen = 1
	}
	for pth := pkg.Path; len(pth) > minLen; pth = path.Dir(pth) {
		found := false
		for _, u := range m.Units {
			if u.Path == pth {
				found = true
				break
			}
		}
		if !found {
			AddUnit(m, UnitEmpty(pth, m.ModulePath, m.Version))
		}
	}
	return m
}

func PackageMeta(fullPath string) *internal.PackageMeta {
	return &internal.PackageMeta{
		Path:              fullPath,
		IsRedistributable: true,
		Name:              path.Base(fullPath),
		Synopsis:          Doc.Synopsis,
		Licenses:          LicenseMetadata(),
	}
}

func ModuleInfo(modulePath, versionString string) *internal.ModuleInfo {
	return &internal.ModuleInfo{
		ModulePath: modulePath,
		Version:    versionString,
		CommitTime: CommitTime,
		// Assume the module path is a GitHub-like repo name.
		SourceInfo:        source.NewGitHubInfo("https://"+modulePath, "", versionString),
		IsRedistributable: true,
		HasGoMod:          true,
	}
}

func DefaultVersionMap() *internal.VersionMap {
	return &internal.VersionMap{
		ModulePath:       ModulePath,
		RequestedVersion: VersionString,
		ResolvedVersion:  VersionString,
		Status:           http.StatusOK,
		GoModPath:        "",
		Error:            "",
	}
}

func AddUnit(m *internal.Module, u *internal.Unit) {
	for _, e := range m.Units {
		if e.Path == u.Path {
			panic(fmt.Sprintf("module already has path %q", e.Path))
		}
	}
	m.Units = append(m.Units, u)
}

func AddLicense(m *internal.Module, lic *licenses.License) {
	m.Licenses = append(m.Licenses, lic)
	dir := path.Dir(lic.FilePath)
	if dir == "." {
		dir = ""
	}
	for _, u := range m.Units {
		if strings.TrimPrefix(u.Path, m.ModulePath+"/") == dir {
			u.Licenses = append(u.Licenses, lic.Metadata)
			u.LicenseContents = append(u.LicenseContents, lic)
		}
	}
}

// ReplaceLicense replaces all licenses having the same file path as lic with lic.
func ReplaceLicense(m *internal.Module, lic *licenses.License) {
	replaceLicense(lic, m.Licenses)
	for _, u := range m.Units {
		for i, lm := range u.Licenses {
			if lm.FilePath == lic.FilePath {
				u.Licenses[i] = lic.Metadata
			}
		}
		replaceLicense(lic, u.LicenseContents)
	}
}

func replaceLicense(lic *licenses.License, lics []*licenses.License) {
	for i, l := range lics {
		if l.FilePath == lic.FilePath {
			lics[i] = lic
		}
	}
}

func UnitEmpty(path, modulePath, version string) *internal.Unit {
	return &internal.Unit{
		UnitMeta: *UnitMeta(path, modulePath, version, "", true),
	}
}

func UnitMeta(path, modulePath, version, name string, isRedistributable bool) *internal.UnitMeta {
	return &internal.UnitMeta{
		Path:              path,
		Name:              name,
		IsRedistributable: isRedistributable,
		Licenses:          LicenseMetadata(),
		ModuleInfo: internal.ModuleInfo{
			ModulePath:        modulePath,
			Version:           version,
			CommitTime:        NowTruncated(),
			IsRedistributable: isRedistributable,
			SourceInfo:        source.NewGitHubInfo("https://"+modulePath, "", version),
		},
	}
}

func constructFullPath(modulePath, suffix string) string {
	if modulePath != stdlib.ModulePath {
		return path.Join(modulePath, suffix)
	}
	return suffix
}

// Documentation returns a Documentation value for the given Go source.
// It panics if there are errors parsing or encoding the source.
func Documentation(goos, goarch, fileContents string) *internal.Documentation {
	fset := token.NewFileSet()
	pf, err := parser.ParseFile(fset, "sample.go", fileContents, parser.ParseComments)
	if err != nil {
		panic(err)
	}
	docPkg := godoc.NewPackage(fset, nil)
	docPkg.AddFile(pf, true)
	src, err := docPkg.Encode(context.Background())
	if err != nil {
		panic(err)
	}

	return &internal.Documentation{
		GOOS:     goos,
		GOARCH:   goarch,
		Synopsis: fmt.Sprintf("This is a package synopsis for GOOS=%s, GOARCH=%s", goos, goarch),
		Source:   src,
	}
}

func LicenseMetadata() []*licenses.Metadata {
	return []*licenses.Metadata{
		{
			Types:    []string{LicenseType},
			FilePath: LicenseFilePath,
			Coverage: licensecheck.Coverage{
				Percent: 100,
				Match:   []licensecheck.Match{{ID: "MIT", Type: 0}},
			},
		},
	}
}

func Licenses() []*licenses.License {
	return []*licenses.License{
		{Metadata: LicenseMetadata()[0], Contents: []byte(`Lorem Ipsum`)},
	}
}

func Imports() []string {
	return []string{"fmt", "path/to/bar"}
}
