// 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"
	oldlicensecheck "github.com/google/licensecheck/old"
	"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)
	DocContents    = `
		// Package p is a package.
		//
		//
		// Links
		//
		// - pkg.go.dev, https://pkg.go.dev
 		package p
		var V int
	`
	Constant = &internal.Symbol{
		Name:     "Constant",
		Synopsis: "const Constant",
		Section:  internal.SymbolSectionConstants,
		Kind:     internal.SymbolKindConstant,
		GOOS:     internal.All,
		GOARCH:   internal.All,
	}
	Variable = &internal.Symbol{
		Name:     "Variable",
		Synopsis: "var Variable",
		Section:  internal.SymbolSectionVariables,
		Kind:     internal.SymbolKindVariable,
		GOOS:     internal.All,
		GOARCH:   internal.All,
	}
	Function = &internal.Symbol{
		Name:     "Function",
		Synopsis: "func Function() error",
		Section:  internal.SymbolSectionFunctions,
		Kind:     internal.SymbolKindFunction,
		GOOS:     internal.All,
		GOARCH:   internal.All,
	}
	FunctionNew = &internal.Symbol{
		Name:       "New",
		Synopsis:   "func New() *Type",
		Section:    internal.SymbolSectionTypes,
		Kind:       internal.SymbolKindFunction,
		ParentName: "Type",
		GOOS:       internal.All,
		GOARCH:     internal.All,
	}
	Type = &internal.Symbol{
		Name:     "Type",
		Synopsis: "type Type struct",
		Section:  internal.SymbolSectionTypes,
		Kind:     internal.SymbolKindType,
		GOOS:     internal.All,
		GOARCH:   internal.All,
		Children: []*internal.Symbol{
			FunctionNew,
			{
				Name:       "Type.Field",
				Synopsis:   "field",
				Section:    internal.SymbolSectionTypes,
				Kind:       internal.SymbolKindField,
				ParentName: "Type",
				GOOS:       internal.All,
				GOARCH:     internal.All,
			},
			{
				Name:       "Type.Method",
				Synopsis:   "method",
				Section:    internal.SymbolSectionTypes,
				Kind:       internal.SymbolKindMethod,
				ParentName: "Type",
				GOOS:       internal.All,
				GOARCH:     internal.All,
			},
		},
	}
)

// 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
		}
	}
	// 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},
		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,
			OldCoverage: oldlicensecheck.Coverage{
				Percent: 100,
				Match:   []oldlicensecheck.Match{{Name: LicenseType, Type: oldlicensecheck.MIT, Percent: 100}},
			},
		},
	}
}

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

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