// Copyright 2020 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 history holds the Go project release history.
package history

import (
	"fmt"
	"html"
	"html/template"
	"sort"
	"strings"
	"time"
)

// A Release describes a single Go release.
type Release struct {
	Version Version
	Date    Date
	Future  bool // if true, the release hasn't happened yet

	// Release content summary.
	Security      *FixSummary   // Security fixes, if any.
	Bug           *FixSummary   // Bug fixes, if any.
	More          template.HTML // Additional release content.
	CustomSummary template.HTML // CustomSummary, if non-empty, replaces the entire release content summary with custom HTML.
}

// FixSummary summarizes fixes in a Go release, listing components and packages involved.
type FixSummary struct {
	Quantifier string          // Optional quantifier. Empty string for unspecified amount of fixes (typical), "a" for a single fix, "two", "three" for multiple fixes, etc.
	Components []template.HTML // Components involved. For example, "cgo", "the compiler", "runtime", "the <code>go</code> command", etc.
	Packages   []string        // Packages involved. For example, "crypto/x509", "net/http", etc.
}

// A Version is a Go release version.
//
// In contrast to Semantic Versioning 2.0.0,
// a version like Go 1.21.0 is considered a major Go release and
// a version like Go 1.21.1 is considered a minor Go release.
// Prior to 1.21.0, trailing zero components were omitted. (See proposal 57631 that changed this.)
//
// See proposal go.dev/issue/32450 for background, details,
// and a discussion of the costs involved in making a change.
type Version struct {
	X int // X is the 1st component of a Go X.Y.Z version. It must be 1 or higher.
	Y int // Y is the 2nd component of a Go X.Y.Z version. It must be 0 or higher.
	Z int // Z is the 3rd component of a Go X.Y.Z version. It must be 0 or higher.
}

// String returns the Go release version string,
// like "1.21.0", "1.21.1", "1.21.2", and so on.
func (v Version) String() string {
	switch {
	// Starting with 1.21.0, trailing 0 components are no longer
	// left out out of the Go version string. See proposal 57631.
	// So it only needs to be done for prior historical versions.
	case v.X == 1 && v.Y < 21 && v.Z == 0:
		return fmt.Sprintf("%d.%d", v.X, v.Y)
	case v.X == 1 && v.Y == 0 && v.Z == 0:
		return fmt.Sprintf("%d", v.X)

	default:
		return fmt.Sprintf("%d.%d.%d", v.X, v.Y, v.Z)
	}
}

// MajorPrefix returns the major version prefix of a Go release version,
// like "1", "1.20", "1.21", and so on.
//
// This prefix can be used when referring to the entire series of releases,
// including the major Go release and all of its subsequent minor releases,
// that this version belongs to.
func (v Version) MajorPrefix() string {
	switch {
	case v.Y != 0:
		return fmt.Sprintf("%d.%d", v.X, v.Y)
	default:
		return fmt.Sprintf("%d", v.X)
	}
}

// Before reports whether version v comes before version u.
func (v Version) Before(u Version) bool {
	if v.X != u.X {
		return v.X < u.X
	}
	if v.Y != u.Y {
		return v.Y < u.Y
	}
	return v.Z < u.Z
}

// A Date represents the date (year, month, day) of a Go release.
//
// This type does not include location information, and
// therefore does not describe a unique 24-hour timespan.
type Date struct {
	Year  int        // Year (e.g., 2009).
	Month time.Month // Month of the year (January = 1, ...).
	Day   int        // Day of the month, starting at 1.
}

func (d Date) String() string {
	return d.Format("2006-01-02")
}

func (d Date) Format(format string) string {
	return time.Date(d.Year, d.Month, d.Day, 0, 0, 0, 0, time.UTC).Format(format)
}

// A Major describes a major Go release and its minor revisions.
type Major struct {
	*Release
	Minor []*Release // oldest first
}

var Majors []*Major = majors() // major versions, newest first

// majors returns a list of major versions, sorted newest first.
func majors() []*Major {
	byVersion := make(map[Version]*Major)
	for _, r := range Releases {
		v := r.Version
		v.Z = 0 // make major version
		m := byVersion[v]
		if m == nil {
			m = new(Major)
			byVersion[v] = m
		}
		if r.Version.Z == 0 {
			m.Release = r
		} else {
			m.Minor = append(m.Minor, r)
		}
	}

	var majors []*Major
	for _, m := range byVersion {
		majors = append(majors, m)
		// minors oldest first
		sort.Slice(m.Minor, func(i, j int) bool {
			return m.Minor[i].Version.Before(m.Minor[j].Version)
		})
	}
	// majors newest first
	sort.Slice(majors, func(i, j int) bool {
		return !majors[i].Version.Before(majors[j].Version)
	})
	return majors
}

// ComponentsAndPackages joins components and packages involved
// in a Go release for the purposes of being displayed on the
// release history page, keeping English grammar rules in mind.
//
// The different special cases are:
//
//	c1
//	c1 and c2
//	c1, c2, and c3
//
//	the p1 package
//	the p1 and p2 packages
//	the p1, p2, and p3 packages
//
//	c1 and [1 package]
//	c1, and [2 or more packages]
//	c1, c2, and [1 or more packages]
func (f *FixSummary) ComponentsAndPackages() template.HTML {
	var buf strings.Builder

	// List components, if any.
	for i, comp := range f.Components {
		if len(f.Packages) == 0 {
			// No packages, so components are joined with more rules.
			switch {
			case i != 0 && len(f.Components) == 2:
				buf.WriteString(" and ")
			case i != 0 && len(f.Components) >= 3 && i != len(f.Components)-1:
				buf.WriteString(", ")
			case i != 0 && len(f.Components) >= 3 && i == len(f.Components)-1:
				buf.WriteString(", and ")
			}
		} else {
			// When there are packages, all components are comma-separated.
			if i != 0 {
				buf.WriteString(", ")
			}
		}
		buf.WriteString(string(comp))
	}

	// Join components and packages using a comma and/or "and" as needed.
	if len(f.Components) > 0 && len(f.Packages) > 0 {
		if len(f.Components)+len(f.Packages) >= 3 {
			buf.WriteString(",")
		}
		buf.WriteString(" and ")
	}

	// List packages, if any.
	if len(f.Packages) > 0 {
		buf.WriteString("the ")
	}
	for i, pkg := range f.Packages {
		switch {
		case i != 0 && len(f.Packages) == 2:
			buf.WriteString(" and ")
		case i != 0 && len(f.Packages) >= 3 && i != len(f.Packages)-1:
			buf.WriteString(", ")
		case i != 0 && len(f.Packages) >= 3 && i == len(f.Packages)-1:
			buf.WriteString(", and ")
		}
		buf.WriteString("<code>" + html.EscapeString(pkg) + "</code>")
	}
	switch {
	case len(f.Packages) == 1:
		buf.WriteString(" package")
	case len(f.Packages) >= 2:
		buf.WriteString(" packages")
	}

	return template.HTML(buf.String())
}
