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

import (
	"fmt"
	"path"
	"strings"
	"time"

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

// Package contains information for an individual package.
type Package struct {
	Module
	Path               string // full import path
	URL                string // relative to this site
	LatestURL          string // link with latest-version placeholder, relative to this site
	IsRedistributable  bool
	Licenses           []LicenseMetadata
	PathAfterDirectory string // for display on the directories tab; used by Directory
	Synopsis           string // for display on the directories tab; used by Directory
}

// Module contains information for an individual module.
type Module struct {
	DisplayVersion    string
	LinkVersion       string
	ModulePath        string
	CommitTime        string
	IsRedistributable bool
	URL               string // relative to this site
	LatestURL         string // link with latest-version placeholder, relative to this site
	Licenses          []LicenseMetadata
}

// createPackage returns a *Package based on the fields of the specified
// internal package and version info.
//
// latestRequested indicates whether the user requested the latest
// version of the package. If so, the returned Package.URL will have the
// structure /<path> instead of /<path>@<version>.
func createPackage(pkg *internal.PackageMeta, mi *internal.ModuleInfo, latestRequested bool) (_ *Package, err error) {
	defer derrors.Wrap(&err, "createPackage(%v, %v, %t)", pkg, mi, latestRequested)

	var modLicenses []*licenses.Metadata
	for _, lm := range pkg.Licenses {
		if path.Dir(lm.FilePath) == "." {
			modLicenses = append(modLicenses, lm)
		}
	}

	m := createModule(mi, modLicenses, latestRequested)
	urlVersion := m.LinkVersion
	if latestRequested {
		urlVersion = internal.LatestVersion
	}
	return &Package{
		Path:              pkg.Path,
		IsRedistributable: pkg.IsRedistributable,
		Licenses:          transformLicenseMetadata(pkg.Licenses),
		Module:            *m,
		URL:               constructPackageURL(pkg.Path, mi.ModulePath, urlVersion),
		LatestURL:         constructPackageURL(pkg.Path, mi.ModulePath, middleware.LatestMinorVersionPlaceholder),
	}, nil
}

// createModule returns a *Module based on the fields of the specified
// versionInfo.
//
// latestRequested indicates whether the user requested the latest
// version of the package. If so, the returned Module.URL will have the
// structure /<path> instead of /<path>@<version>.
func createModule(mi *internal.ModuleInfo, licmetas []*licenses.Metadata, latestRequested bool) *Module {
	urlVersion := linkVersion(mi.Version, mi.ModulePath)
	if latestRequested {
		urlVersion = internal.LatestVersion
	}
	return &Module{
		DisplayVersion:    displayVersion(mi.Version, mi.ModulePath),
		LinkVersion:       linkVersion(mi.Version, mi.ModulePath),
		ModulePath:        mi.ModulePath,
		CommitTime:        elapsedTime(mi.CommitTime),
		IsRedistributable: mi.IsRedistributable,
		Licenses:          transformLicenseMetadata(licmetas),
		URL:               constructModuleURL(mi.ModulePath, urlVersion),
		LatestURL:         constructModuleURL(mi.ModulePath, middleware.LatestMinorVersionPlaceholder),
	}
}

func constructModuleURL(modulePath, linkVersion string) string {
	url := "/"
	if modulePath != stdlib.ModulePath {
		url += "mod/"
	}
	url += modulePath
	if linkVersion != internal.LatestVersion {
		url += "@" + linkVersion
	}
	return url
}

func constructPackageURL(pkgPath, modulePath, linkVersion string) string {
	if linkVersion == internal.LatestVersion {
		return "/" + pkgPath
	}
	if pkgPath == modulePath || modulePath == stdlib.ModulePath {
		return fmt.Sprintf("/%s@%s", pkgPath, linkVersion)
	}
	return fmt.Sprintf("/%s@%s/%s", modulePath, linkVersion, strings.TrimPrefix(pkgPath, modulePath+"/"))
}

// effectiveName returns either the command name or package name.
func effectiveName(pkgPath, pkgName string) string {
	if pkgName != "main" {
		return pkgName
	}
	var prefix string // package path without version
	if pkgPath[len(pkgPath)-3:] == "/v1" {
		prefix = pkgPath[:len(pkgPath)-3]
	} else {
		prefix, _, _ = module.SplitPathVersion(pkgPath)
	}
	_, base := path.Split(prefix)
	return base
}

// packageHTMLTitle constructs the details page title for pkg.
// The string will appear in the <title> element (and thus
// the browser tab).
func packageHTMLTitle(pkgPath, pkgName string) string {
	if pkgName != "main" {
		return pkgName + " package"
	}
	return effectiveName(pkgPath, pkgName) + " command"
}

type breadcrumb struct {
	Links    []link
	Current  string
	CopyData string
}

type link struct {
	Href, Body string
}

// breadcrumbPath builds HTML that displays pkgPath as a sequence of links
// to its parents.
// pkgPath is a slash-separated path, and may be a package import path or a directory.
// modPath is the package's module path. This will be a prefix of pkgPath, except
// within the standard library.
// version is the version for the module, or LatestVersion.
//
// See TestBreadcrumbPath for examples.
func breadcrumbPath(pkgPath, modPath, requestedVersion string) breadcrumb {
	if pkgPath == stdlib.ModulePath {
		return breadcrumb{Current: "Standard library"}
	}
	// Obtain successive prefixes of pkgPath, stopping at modPath,
	// or for the stdlib, at the end.
	minLen := len(modPath) - 1
	if modPath == stdlib.ModulePath {
		minLen = 1
	}
	var dirs []string
	for dir := pkgPath; len(dir) > minLen && len(path.Dir(dir)) < len(dir); dir = path.Dir(dir) {
		dirs = append(dirs, dir)
	}
	// Construct the path elements of the result.
	// They will be in reverse order of dirs.
	// The first dir is the current page. If it is the only one, leave it
	// as is. Otherwise, use its base. In neither case does it get a link.
	d := dirs[0]
	if len(dirs) > 1 {
		d = path.Base(d)
	}
	b := breadcrumb{Current: d}
	// Make all the other parts into links.
	b.Links = make([]link, len(dirs)-1)
	for i := 1; i < len(dirs); i++ {
		href := "/" + dirs[i]
		if requestedVersion != internal.LatestVersion {
			href += "@" + linkVersion(requestedVersion, modPath)
		}
		el := dirs[i]
		if i != len(dirs)-1 {
			el = path.Base(el)
		}
		b.Links[len(b.Links)-i] = link{href, el}
	}
	// Add a "copy" button for the path.
	b.CopyData = pkgPath
	return b
}

// moduleHTMLTitle constructs the <title> contents, for tabs in the browser.
func moduleHTMLTitle(modulePath string) string {
	if modulePath == stdlib.ModulePath {
		return "stdlib"
	}
	return modulePath + " module"
}

// elapsedTime takes a date and returns returns human-readable,
// relative timestamps based on the following rules:
// (1) 'X hours ago' when X < 6
// (2) 'today' between 6 hours and 1 day ago
// (3) 'Y days ago' when Y < 6
// (4) A date formatted like "Jan 2, 2006" for anything further back
func elapsedTime(date time.Time) string {
	elapsedHours := int(time.Since(date).Hours())
	if elapsedHours == 1 {
		return "1 hour ago"
	} else if elapsedHours < 6 {
		return fmt.Sprintf("%d hours ago", elapsedHours)
	}

	elapsedDays := elapsedHours / 24
	if elapsedDays < 1 {
		return "today"
	} else if elapsedDays == 1 {
		return "1 day ago"
	} else if elapsedDays < 6 {
		return fmt.Sprintf("%d days ago", elapsedDays)
	}

	return date.Format("Jan _2, 2006")
}
