// 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/stdlib"
	"golang.org/x/pkgsite/internal/testing/htmlcheck"
)

// Page describes a discovery site web page for a package, module or directory.
type Page struct {
	ModulePath       string
	Suffix           string // package or directory path after module path; empty for a module
	Version          string
	FormattedVersion string
	Title            string
	LicenseType      string
	LicenseFilePath  string
	IsLatest         bool   // is this the latest version of this module?
	LatestLink       string // href of "Go to latest" link
	PackageURLFormat string // the relative package URL, with one %s for "@version"; also used for dirs
	ModuleURL        string // the relative module URL
}

// Overview describes the contents of the overview tab.
type Overview struct {
	ModuleLink     string // relative link to module page
	ModuleLinkText string
	RepoURL        string
	PackageURL     string
	ReadmeContent  string
	ReadmeSource   string
}

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

// PackageHeader checks a details page header for a package.
func PackageHeader(p *Page, versionedURL bool) htmlcheck.Checker {
	fv := p.FormattedVersion
	if fv == "" {
		fv = p.Version
	}
	curBreadcrumb := path.Base(p.Suffix)
	if p.Suffix == "" {
		curBreadcrumb = p.ModulePath
	}
	return in("",
		in("span.DetailsHeader-breadcrumbCurrent", exactText(curBreadcrumb)),
		in("h1.DetailsHeader-title", exactTextCollapsed(p.Title)),
		in("div.DetailsHeader-version", exactText(fv)),
		versionBadge(p),
		licenseInfo(p, packageURLPath(p, versionedURL)),
		packageTabLinks(p, versionedURL),
		moduleInHeader(p, versionedURL))
}

// ModuleHeader checks a details page header for a module.
func ModuleHeader(p *Page, versionedURL bool) htmlcheck.Checker {
	fv := p.FormattedVersion
	if fv == "" {
		fv = p.Version
	}
	curBreadcrumb := p.ModulePath
	if p.ModulePath == stdlib.ModulePath {
		curBreadcrumb = "Standard library"
	}
	return in("",
		in("span.DetailsHeader-breadcrumbCurrent", exactText(curBreadcrumb)),
		in("h1.DetailsHeader-title", exactTextCollapsed(p.Title)),
		in("div.DetailsHeader-version", exactText(fv)),
		versionBadge(p),
		licenseInfo(p, moduleURLPath(p, versionedURL)),
		moduleTabLinks(p, versionedURL))
}

// DirectoryHeader checks a details page header for a directory.
func DirectoryHeader(p *Page, versionedURL bool) htmlcheck.Checker {
	fv := p.FormattedVersion
	if fv == "" {
		fv = p.Version
	}
	return in("",
		in("span.DetailsHeader-breadcrumbCurrent", exactText(path.Base(p.Suffix))),
		in("h1.DetailsHeader-title", exactTextCollapsed(p.Title)),
		in("div.DetailsHeader-version", exactText(fv)),
		// directory pages don't show a header badge
		in("div.DetailsHeader-version", exactText(fv)),
		licenseInfo(p, packageURLPath(p, versionedURL)),
		// directory module links are always versioned (see b/144217401)
		moduleInHeader(p, true))
}

// 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)))
}

// OverviewDetails checks the details section of an overview tab.
func OverviewDetails(ov *Overview) htmlcheck.Checker {
	var pkg htmlcheck.Checker
	if ov.PackageURL != "" {
		pkg = in(".Overview-sourceCodeLink a:nth-of-type(2)",
			href(ov.PackageURL),
			exactText(ov.PackageURL))
	}
	return in("",
		in("div.Overview-module > a",
			href(ov.ModuleLink),
			exactText(ov.ModuleLinkText)),
		in(".Overview-sourceCodeLink a:nth-of-type(1)",
			href(ov.RepoURL),
			exactText(ov.RepoURL)),
		pkg,
		in(".Overview-readmeContent", text(ov.ReadmeContent)),
		in(".Overview-readmeSource", exactText("Source: "+ov.ReadmeSource)))
}

// versionBadge checks the latest-version badge on a header.
func versionBadge(p *Page) htmlcheck.Checker {
	class := "DetailsHeader-badge"
	if p.IsLatest {
		class += "--latest"
	} else {
		class += "--goToLatest"
	}
	return in("div.DetailsHeader-badge",
		attr("class", `\b`+regexp.QuoteMeta(class)+`\b`), // the badge has this class too
		in("a", href(p.LatestLink), exactText("Go to latest")))
}

// licenseInfo checks the license part of the info label in the header.
func licenseInfo(p *Page, urlPath string) htmlcheck.Checker {
	if p.LicenseType == "" {
		return in("[data-test-id=DetailsHeader-infoLabelLicense]", text("None detected"))
	}
	return in("[data-test-id=DetailsHeader-infoLabelLicense] a",
		href(fmt.Sprintf("%s?tab=licenses#lic-0", urlPath)),
		exactText(p.LicenseType))
}

// moduleInHeader checks the module part of the info label in the header.
func moduleInHeader(p *Page, versionedURL bool) htmlcheck.Checker {
	modURL := moduleURLPath(p, versionedURL)
	text := p.ModulePath
	if p.ModulePath == stdlib.ModulePath {
		text = "Standard library"
	}
	return in("a[data-test-id=DetailsHeader-infoLabelModule]", href(modURL), exactText(text))
}

// Check that all the navigation tabs link to the same package at the same version.
func packageTabLinks(p *Page, versionedURL bool) htmlcheck.Checker {
	return inAll("a.DetailsNav-link[href]",
		attr("href", "^"+regexp.QuoteMeta(packageURLPath(p, versionedURL))))
}

// Check that all the navigation tabs link to the same module at the same version.
func moduleTabLinks(p *Page, versionedURL bool) htmlcheck.Checker {
	return inAll("a.DetailsNav-link[href]",
		attr("href", "^"+regexp.QuoteMeta(moduleURLPath(p, versionedURL))))
}

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

func moduleURLPath(p *Page, versioned bool) string {
	if versioned {
		return p.ModuleURL + "@" + p.Version
	}
	return p.ModuleURL
}
