// 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 pagecheck implements HTML checkers for discovery site pages.
// It uses the general-purpose checkers in internal/testing/htmlcheck to define
// site-specific checkers.
package pagecheck

import (
	"fmt"
	"path"
	"regexp"

	"golang.org/x/pkgsite/internal/testing/htmlcheck"
)

// Page describes a discovery site web page for a package, module or directory.
type Page struct {
	// ModulePath is the module path for the unit page.
	ModulePath string

	// Suffix is the unit path element after module path; empty for a module
	Suffix string

	// Version is the full version of the module, or the go tag if it is the
	// stdlib.
	Version string

	// FormattedVersion is the version of the module, or go tag if it is the
	// stdlib. The version string may be truncated if it is a pseudoversion.
	FormattedVersion string

	// Title is output of frontend.pageTitle.
	Title string

	// LicenseType is name of the license.
	LicenseType string

	// LicenseFilePath is the path of the license relative to the module directory.
	LicenseFilePath string

	// IsLatestMinor is the latest minor version of this module.
	IsLatestMinor bool

	// MissingInMinor says that the unit is missing in the latest minor version of this module.
	MissingInMinor bool

	// IsLatestMajor is the latest major version of this series.
	IsLatestMajor bool

	// LatestLink is the href of "Go to latest" link.
	LatestLink string

	// LatestMajorVersion is the suffix of the latest major version, empty if
	// v0 or v1.
	LatestMajorVersion string

	// LatestMajorVersionLink is the link to the latest major version of the
	// unit. If the unit does not exist at the latest major version, it is a
	// link to the latest major version of the module.
	LatestMajorVersionLink string

	// UnitURLFormat is the relative unit URL, with one %s for "@version".
	UnitURLFormat string

	// ModuleURL is the relative module URL.
	ModuleURL string

	// CommitTime is the output of frontend.absoluteTime for the commit time.
	CommitTime string
}

var (
	in        = htmlcheck.In
	text      = htmlcheck.HasText
	exactText = htmlcheck.HasExactText
	attr      = htmlcheck.HasAttr
	href      = htmlcheck.HasHref
)

// UnitHeader checks a main page header for a unit.
func UnitHeader(p *Page, versionedURL bool, isPackage bool) htmlcheck.Checker {
	urlPath := unitURLPath(p, versionedURL)
	curBreadcrumb := path.Base(p.Suffix)
	if p.Suffix == "" {
		curBreadcrumb = p.ModulePath
	}
	licenseText := p.LicenseType
	licenseLink := urlPath + "?tab=licenses"
	if p.LicenseType == "" {
		licenseText = "not legal advice"
		licenseLink = "/license-policy"
	}

	importsDetails := in("",
		in(`[data-test-id="UnitHeader-imports"]`,
			in("a",
				href(urlPath+"?tab=imports"),
				text(`Imports: [0-9]+\+?`))),
		in(`[data-test-id="UnitHeader-importedby"]`,
			in("a",
				href(urlPath+"?tab=importedby"),
				text(`Imported by: [0-9]+\+?`))))
	if !isPackage {
		importsDetails = nil
	}

	var majorVersionBanner htmlcheck.Checker
	if p.IsLatestMajor {
		majorVersionBanner = htmlcheck.NotIn(`[data-test-id="UnitHeader-majorVersionBanner"]`)
	} else {
		majorVersionBanner = in(`[data-test-id="UnitHeader-majorVersionBanner"]`,
			text("The highest tagged major version is"),
			in("a",
				href(p.LatestMajorVersionLink),
				text(p.LatestMajorVersion),
			),
		)
	}
	return in("",
		versionBadge(p),
		in(`[data-test-id="UnitHeader-breadcrumbCurrent"]`, text(curBreadcrumb)),
		in(`[data-test-id="UnitHeader-title"]`, text(p.Title)),
		majorVersionBanner,
		in(`[data-test-id="UnitHeader-version"]`,
			in("a",
				href("?tab=versions"),
				exactText("Version: "+p.FormattedVersion))),
		in(`[data-test-id="UnitHeader-commitTime"]`,
			text(p.CommitTime)),
		in(`[data-test-id="UnitHeader-licenses"]`,
			in("a",
				href(licenseLink),
				text(licenseText))),
		importsDetails)
}

// UnitReadme checks the readme section of the main page.
func UnitReadme() htmlcheck.Checker {
	return in(".UnitReadme",
		in(`[data-test-id="Unit-readmeContent"]`, text("readme")),
	)
}

// UnitDoc checks the doc section of the main page.
func UnitDoc() htmlcheck.Checker {
	return in(".Documentation", text(`Overview`))
}

// UnitDirectories checks the directories section of the main page.
// If firstHref isn't empty, it and firstText should exactly match
// href and text of the first link in the Directories table.
func UnitDirectories(firstHref, firstText string) htmlcheck.Checker {
	var link htmlcheck.Checker
	if firstHref != "" {
		link = in(`[data-test-id="UnitDirectories-table"] a`, href(firstHref), exactText(firstText))
	}
	return in("",
		in("th:nth-child(1)", text("^Path$")),
		in("th:nth-child(2)", text("^Synopsis$")),
		link)
}

// CanonicalURLPath checks the canonical url for the unit on the page.
func CanonicalURLPath(path string) htmlcheck.Checker {
	return in(".js-canonicalURLPath", attr("data-canonical-url-path", path))
}

// SubdirectoriesDetails checks the detail section of a subdirectories tab.
// If firstHref isn't empty, it and firstText should exactly match
// href and text of the first link in the Directories table.
func SubdirectoriesDetails(firstHref, firstText string) htmlcheck.Checker {
	var link htmlcheck.Checker
	if firstHref != "" {
		link = in("table.Directories a", href(firstHref), exactText(firstText))
	}
	return in("",
		in("th:nth-child(1)", text("^Path$")),
		in("th:nth-child(2)", text("^Synopsis$")),
		link)
}

// LicenseDetails checks the details section of a license tab.
func LicenseDetails(ltype, bodySubstring, source string) htmlcheck.Checker {
	return in("",
		in(".License",
			text(regexp.QuoteMeta(ltype)),
			text("This is not legal advice"),
			in("a",
				href("/license-policy"),
				exactText("Read disclaimer.")),
			in(".License-contents",
				text(regexp.QuoteMeta(bodySubstring)))),
		in(".License-source",
			exactText("Source: "+source)))
}

// versionBadge checks the latest-version badge on a header.
func versionBadge(p *Page) htmlcheck.Checker {
	class := "DetailsHeader-badge"
	switch {
	case p.MissingInMinor:
		class += "--notAtLatest"
	case p.IsLatestMinor:
		class += "--latest"
	default:
		class += "--goToLatest"
	}
	return in(`[data-test-id="UnitHeader-minorVersionBanner"]`,
		attr("class", `\b`+regexp.QuoteMeta(class)+`\b`), // the badge has this class too
		in("a", href(p.LatestLink), text("Go to latest")))
}

func unitURLPath(p *Page, versioned bool) string {
	v := ""
	if versioned {
		v = "@" + p.Version
	}
	return fmt.Sprintf(p.UnitURLFormat, v)
}
