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

import (
	"errors"
	"path"
	"strconv"
	"strings"
	"time"

	"golang.org/x/mod/module"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/licenses"
	"golang.org/x/pkgsite/internal/source"
	"golang.org/x/pkgsite/internal/stdlib"
)

const (
	// LatestVersion signifies the latest available version in requests to the
	// proxy client.
	LatestVersion = "latest"

	// MainVersion represents the main branch.
	MainVersion = "main"

	// MasterVersion represents the master branch.
	MasterVersion = "master"

	// UnknownModulePath signifies that the module path for a given package
	// path is ambiguous or not known. This is because requests to the
	// frontend can come in the form of <import-path>[@<version>], and it is
	// not clear which part of the import-path is the module path.
	UnknownModulePath = "unknownModulePath"
)

// DefaultBranches are default branches that are supported by pkgsite.
var DefaultBranches = map[string]bool{
	MainVersion:   true,
	MasterVersion: true,
}

// ModuleInfo holds metadata associated with a module.
type ModuleInfo struct {
	ModulePath        string
	Version           string
	CommitTime        time.Time
	IsRedistributable bool
	// HasGoMod describes whether the module zip has a go.mod file.
	HasGoMod   bool
	SourceInfo *source.Info

	// Deprecated describes whether the module is deprecated.
	Deprecated bool
	// DeprecationComment is the comment describing the deprecation, if any.
	DeprecationComment string
	// Retracted describes whether the module version is retracted.
	Retracted bool
	// RetractionRationale is the reason for the retraction, if any.
	RetractionRationale string
}

// VersionMap holds metadata associated with module queries for a version.
type VersionMap struct {
	ModulePath       string
	RequestedVersion string
	ResolvedVersion  string
	GoModPath        string
	Status           int
	Error            string
	UpdatedAt        time.Time
}

// SeriesPath returns the series path for the module.
//
// A series is a group of modules that share the same base path and are assumed
// to be major-version variants.
//
// The series path is the module path without the version. For most modules,
// this will be the module path for all module versions with major version 0 or
// 1. For gopkg.in modules, the series path does not correspond to any module
// version.
//
// Examples:
// The module paths "a/b" and "a/b/v2"  both have series path "a/b".
// The module paths "gopkg.in/yaml.v1" and "gopkg.in/yaml.v2" both have series
// path "gopkg.in/yaml".
func (v *ModuleInfo) SeriesPath() string {
	return SeriesPathForModule(v.ModulePath)
}

// SeriesPathForModule returns the series path for the provided modulePath.
func SeriesPathForModule(modulePath string) string {
	seriesPath, _, _ := module.SplitPathVersion(modulePath)
	return seriesPath
}

// MajorVersionForModule returns the final "vN" from the module path, if any.
// It returns the empty string if the module path is malformed.
// Examples:
//
//	"m.com" => ""
//	"m.com/v2" => "v2"
//	"gpkg.in/m.v1 = "v1"
func MajorVersionForModule(modulePath string) string {
	_, v, _ := module.SplitPathVersion(modulePath)
	return strings.TrimLeft(v, "/.")
}

// SeriesPathAndMajorVersion splits modulePath into a series path and a
// numeric major version.
// If the path doesn't have a "vN" suffix, it returns 1.
// If the module path is invalid, it returns ("", 0).
func SeriesPathAndMajorVersion(modulePath string) (string, int) {
	seriesPath, v, ok := module.SplitPathVersion(modulePath)
	if !ok {
		return "", 0
	}
	if v == "" {
		return seriesPath, 1
	}
	// First two characters are either ".v" or "/v".
	n, err := strconv.Atoi(v[2:])
	if err != nil {
		return "", 0
	}
	return seriesPath, n
}

// Suffix returns the suffix of the fullPath. It assumes that basePath is a
// prefix of fullPath. If fullPath and basePath are the same, the empty string
// is returned.
func Suffix(fullPath, basePath string) string {
	return strings.TrimPrefix(strings.TrimPrefix(fullPath, basePath), "/")
}

// V1Path returns the path for version 1 of the package whose import path
// is fullPath. If modulePath is the standard library, then V1Path returns
// fullPath.
func V1Path(fullPath, modulePath string) string {
	if modulePath == stdlib.ModulePath {
		return fullPath
	}
	return path.Join(SeriesPathForModule(modulePath), Suffix(fullPath, modulePath))
}

// A Module is a specific, reproducible build of a module.
type Module struct {
	ModuleInfo
	// Licenses holds all licenses within this module version, including those
	// that may be contained in nested subdirectories.
	Licenses []*licenses.License
	Units    []*Unit
}

// Packages returns all of the units for a module that are packages.
func (m *Module) Packages() []*Unit {
	var pkgs []*Unit
	for _, u := range m.Units {
		if u.IsPackage() {
			pkgs = append(pkgs, u)
		}
	}
	return pkgs
}

// IndexVersion holds the version information returned by the module index.
type IndexVersion struct {
	Path      string
	Version   string
	Timestamp time.Time
}

// ModuleVersionState holds a worker module version state.
type ModuleVersionState struct {
	ModulePath string
	Version    string

	// IndexTimestamp is the timestamp received from the Index for this version,
	// which should correspond to the time this version was committed to the
	// Index.
	//
	// This may be nil if the request only came via frontend fetch, or the
	// status is not a 2xx status.
	IndexTimestamp *time.Time

	// CreatedAt is the time this version was originally inserted into the
	// module version state table.
	CreatedAt time.Time

	// Status is the most recent HTTP status code received from the Fetch service
	// for this version, or nil if no request to the fetch service has been made.
	Status int
	// Error is the most recent HTTP response body received from the Fetch
	// service, for a response with an unsuccessful status code. It is used for
	// debugging only, and has no semantic significance.
	Error string
	// TryCount is the number of times a fetch of this version has been
	// attempted.
	TryCount int
	// LastProcessedAt is the last time this version was updated with a result
	// from the fetch service.
	LastProcessedAt *time.Time
	// NextProcessedAfter is the next time a fetch for this version should be
	// attempted.
	NextProcessedAfter time.Time

	// AppVersion is the value of the GAE_VERSION environment variable, which is
	// set by app engine. It is a timestamp in the format 20190709t112655 that
	// is close to, but not the same as, the deployment time. For example, the
	// deployment time for the above timestamp might be Jul 9, 2019, 11:29:59 AM.
	AppVersion string

	// HasGoMod says whether the zip file has a go.mod file.
	HasGoMod bool

	// GoModPath is the path declared in the go.mod file fetched from the proxy.
	GoModPath string

	// NumPackages it the number of packages that were processed as part of the
	// module (regardless of whether the processing was successful).
	NumPackages *int
}

// PackageVersionState holds a worker package version state. It is associated
// with a given module version state.
type PackageVersionState struct {
	PackagePath string
	ModulePath  string
	Version     string
	Status      int
	Error       string
}

// A Modver holds a module path and version.
type Modver struct {
	Path    string
	Version string
}

func (mv Modver) String() string {
	return mv.Path + "@" + mv.Version
}

// ParseModver parses a string of the form M@V into a Modver.
func ParseModver(s string) (mv Modver, err error) {
	defer derrors.Wrap(&err, "ParseModver(%q)", s)
	parts := strings.Split(s, "@")
	if len(parts) != 2 {
		return mv, errors.New("should be module@version")
	}
	return Modver{Path: parts[0], Version: parts[1]}, nil
}
