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

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"strings"

	"github.com/Masterminds/squirrel"
	"github.com/lib/pq"
	"golang.org/x/mod/semver"
	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/database"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/log"
	"golang.org/x/pkgsite/internal/middleware/stats"
	"golang.org/x/pkgsite/internal/version"
	"golang.org/x/sync/errgroup"
)

// GetVersionsForPath returns a list of tagged versions sorted in
// descending semver order if any exist. If none, it returns the 10 most
// recent from a list of pseudo-versions sorted in descending semver order.
func (db *DB) GetVersionsForPath(ctx context.Context, path string) (_ []*internal.ModuleInfo, err error) {
	defer derrors.WrapStack(&err, "GetVersionsForPath(ctx, %q)", path)
	defer stats.Elapsed(ctx, "GetVersionsForPath")()

	versions, err := getPathVersions(ctx, db, path, version.TypeRelease, version.TypePrerelease)
	if err != nil {
		return nil, err
	}
	if len(versions) != 0 {
		return versions, nil
	}
	versions, err = getPathVersions(ctx, db, path, version.TypePseudo)
	if err != nil {
		return nil, err
	}
	return versions, nil
}

// getPathVersions returns a list of versions sorted in descending semver
// order. The version types included in the list are specified by a list of
// VersionTypes.
func getPathVersions(ctx context.Context, db *DB, path string, versionTypes ...version.Type) (_ []*internal.ModuleInfo, err error) {
	defer derrors.WrapStack(&err, "getPathVersions(ctx, db, %q, %v)", path, versionTypes)

	baseQuery := `
	SELECT
		m.module_path,
		m.version,
		m.commit_time,
		m.redistributable,
		m.has_go_mod,
		m.source_info
	FROM modules m
	INNER JOIN units u
		ON u.module_id = m.id
	WHERE
		u.v1path_id = (
			SELECT u2.v1path_id
			FROM units as u2
			INNER JOIN paths p
			ON p.id = u2.path_id
			WHERE p.path = $1
			LIMIT 1
		)
		AND version_type in (%s)
	ORDER BY
		m.incompatible,
		m.module_path DESC,
		m.sort_version DESC %s`

	queryEnd := `;`
	if len(versionTypes) == 0 {
		return nil, fmt.Errorf("error: must specify at least one version type")
	} else if len(versionTypes) == 1 && versionTypes[0] == version.TypePseudo {
		queryEnd = `LIMIT 10;`
	} else {
		// When a page shows too many versions, it can result in a Chrome CSS
		// bug: https://bugs.chromium.org/p/chromium/issues/detail?id=688640.
		// For example,
		// https://pkg.go.dev/github.com/aws/aws-sdk-go/aws/signer/v4?tab=versions.
		// It's not that useful to see that many versions on a page anyway, so
		// just limit to 800 versions.
		queryEnd = `LIMIT 800;`
	}
	query := fmt.Sprintf(baseQuery, versionTypeExpr(versionTypes), queryEnd)
	var versions []*internal.ModuleInfo
	collect := func(rows *sql.Rows) error {
		mi, err := scanModuleInfo(rows.Scan)
		if err != nil {
			return fmt.Errorf("row.Scan(): %v", err)
		}
		versions = append(versions, mi)
		return nil
	}
	if err := db.db.RunQuery(ctx, query, collect, path); err != nil {
		return nil, err
	}
	if err := populateLatestInfos(ctx, db, versions); err != nil {
		return nil, err
	}
	return versions, nil
}

// versionTypeExpr returns a comma-separated list of version types,
// for use in a clause like "WHERE version_type IN (%s)"
func versionTypeExpr(vts []version.Type) string {
	var vs []string
	for _, vt := range vts {
		vs = append(vs, fmt.Sprintf("'%s'", vt.String()))
	}
	return strings.Join(vs, ", ")
}

func populateLatestInfo(ctx context.Context, db *DB, mi *internal.ModuleInfo) (err error) {
	defer derrors.WrapStack(&err, "populateLatestInfo(%q)", mi.ModulePath)

	// Get information about retractions an deprecations, and apply it.
	lmv, err := db.GetLatestModuleVersions(ctx, mi.ModulePath)
	if err != nil {
		return err
	}
	if lmv != nil {
		lmv.PopulateModuleInfo(mi)
	}
	return nil
}

func populateLatestInfos(ctx context.Context, db *DB, mis []*internal.ModuleInfo) (err error) {
	defer derrors.WrapStack(&err, "populateLatestInfos(%d ModuleInfos)", len(mis))

	// Collect the LatestModuleVersions for all modules in the list.
	lmvs := map[string]*internal.LatestModuleVersions{}
	for _, mi := range mis {
		if _, ok := lmvs[mi.ModulePath]; !ok {
			lmv, err := db.GetLatestModuleVersions(ctx, mi.ModulePath)
			if err != nil {
				return err
			}
			lmvs[mi.ModulePath] = lmv
		}
	}
	// Use the collected LatestModuleVersions to populate the ModuleInfos.
	for _, mi := range mis {
		lmv := lmvs[mi.ModulePath]
		if lmv != nil {
			lmv.PopulateModuleInfo(mi)
		}
	}
	return nil
}

// GetLatestInfo returns the latest information about the unit in the module.
// See internal.LatestInfo for documentation about the returned values.
// If latestUnitMeta is non-nil, it is the result of GetUnitMeta(unitPath, internal.UnknownModulePath, internal.LatestVersion).
// That can save a redundant call to GetUnitMeta here.
func (db *DB) GetLatestInfo(ctx context.Context, unitPath, modulePath string, latestUnitMeta *internal.UnitMeta) (latest internal.LatestInfo, err error) {
	defer derrors.WrapStack(&err, "DB.GetLatestInfo(ctx, %q, %q)", unitPath, modulePath)
	defer stats.Elapsed(ctx, "DB.GetLatestInfo")()

	group, gctx := errgroup.WithContext(ctx)

	if latestUnitMeta != nil {
		latest.MinorVersion = latestUnitMeta.Version
		latest.MinorModulePath = latestUnitMeta.ModulePath
	} else {
		group.Go(func() error {
			um, err := db.GetUnitMeta(gctx, unitPath, internal.UnknownModulePath, version.Latest)
			if err != nil {
				return err
			}
			latest.MinorVersion = um.Version
			latest.MinorModulePath = um.ModulePath
			return nil
		})
	}
	group.Go(func() (err error) {
		latest.MajorModulePath, latest.MajorUnitPath, err = db.getLatestMajorVersion(gctx, unitPath, modulePath)
		return err
	})
	group.Go(func() (err error) {
		latest.UnitExistsAtMinor, err = db.unitExistsAtLatest(gctx, unitPath, modulePath)
		return err
	})

	if err := group.Wait(); err != nil {
		return internal.LatestInfo{}, err
	}
	return latest, nil
}

// getLatestMajorVersion returns the latest module path and the full package path
// of the latest version found, given the fullPath and the modulePath.
// For example, in the module path "github.com/casbin/casbin", there
// is another module path with a greater major version "github.com/casbin/casbin/v3".
// This function will return "github.com/casbin/casbin/v3" or the input module path
// if no later module path was found. It also returns the full package path at the
// latest module version if it exists. If not, it returns the module path.
//
// getLatestMajorVersion only considers tagged (non-pseudo) versions. If there are none,
// it returns empty strings.
func (db *DB) getLatestMajorVersion(ctx context.Context, fullPath, modulePath string) (modPath, pkgPath string, err error) {
	defer derrors.WrapStack(&err, "DB.getLatestMajorVersion2(%q)", modulePath)
	defer stats.Elapsed(ctx, "DB.getLatestMajorVersion")()

	// Collect all the non-deprecated module paths for the series that have at
	// least one good version, along with that good version. A good version
	// is both servable (in the modules table) and not retracted.
	seriesPath := internal.SeriesPathForModule(modulePath)
	q, args, err := squirrel.Select("p.path", "l.good_version").
		From("latest_module_versions l").
		Join("paths p ON p.id = l.module_path_id").
		Where(squirrel.Eq{"l.series_path": seriesPath}).
		Where("NOT l.deprecated").
		Where(squirrel.NotEq{"l.good_version": ""}).
		PlaceholderFormat(squirrel.Dollar).
		ToSql()
	if err != nil {
		return "", "", err
	}

	type pathver struct {
		path, version string
	}

	var pathvers []pathver
	err = db.db.RunQuery(ctx, q, func(rows *sql.Rows) error {
		var pv pathver
		if err := rows.Scan(&pv.path, &pv.version); err != nil {
			return err
		}
		pathvers = append(pathvers, pv)
		return nil
	}, args...)
	if err != nil {
		return "", "", err
	}

	// Find the highest tagged version from among the (module path, good
	// version) pairs.
	var max pathver
	for _, pv := range pathvers {
		if version.IsPseudo(pv.version) {
			continue
		}
		// Use semver.Compare, not version.Later, because we don't want to prefer
		// release to prerelease: we want v2.0.0-pre over v1.0.0.
		if max.path == "" || semver.Compare(pv.version, max.version) > 0 {
			max = pv
		}
	}

	// No highest tagged version: return empty strings.
	if max.path == "" {
		return "", "", nil
	}

	// Find the unit path at the max-version module path.
	v1Path := internal.V1Path(fullPath, modulePath)
	row := db.db.QueryRow(ctx, `
		SELECT p.path
		FROM units u
		INNER JOIN modules m ON m.id = u.module_id
		INNER JOIN paths p ON p.id = u.path_id
		INNER JOIN paths p2 ON p2.id = u.v1path_id
		WHERE p2.path = $1 AND m.module_path = $2 AND m.version = $3`,
		v1Path, max.path, max.version)
	var path string
	switch err := row.Scan(&path); err {
	case nil:
		return max.path, path, nil
	case sql.ErrNoRows:
		return max.path, max.path, nil
	default:
		return "", "", err
	}
}

// unitExistsAtLatest reports whether unitPath exists at the latest version of modulePath.
func (db *DB) unitExistsAtLatest(ctx context.Context, unitPath, modulePath string) (unitExists bool, err error) {
	defer derrors.WrapStack(&err, "DB.unitExistsAtLatest(ctx, %q, %q)", unitPath, modulePath)
	defer stats.Elapsed(ctx, "DB.unitExistsAtLatest")()

	// Find the latest version of the module path in the modules table.
	var latestGoodVersion string
	lmv, err := db.GetLatestModuleVersions(ctx, modulePath)
	if err != nil {
		return false, err
	}
	if lmv != nil && lmv.GoodVersion != "" {
		// If we have latest-version info, use it.
		latestGoodVersion = lmv.GoodVersion
	} else {
		// Otherwise, query the modules table, ignoring all adjustments for incompatible and retracted versions.
		err := db.db.QueryRow(ctx, `
			SELECT version
			FROM modules
			WHERE module_path = $1
			ORDER BY
				version_type = 'release' DESC,
				sort_version DESC
			LIMIT 1
		`, modulePath).Scan(&latestGoodVersion)
		if err != nil {
			return false, err
		}
	}
	if latestGoodVersion == "" {
		return true, nil
	}
	// See if the unit path exists at that version.
	var x int
	err = db.db.QueryRow(ctx, `
		SELECT 1
		FROM units u
		INNER JOIN paths p ON p.id = u.path_id
		INNER JOIN modules m ON m.id = u.module_id
		WHERE p.path = $1 AND m.module_path = $2 AND m.version = $3
	`, unitPath, modulePath, latestGoodVersion).Scan(&x)
	switch err {
	case nil:
		return true, nil
	case sql.ErrNoRows:
		return false, nil
	default:
		return false, err
	}
}

func (db *DB) getMultiLatestModuleVersions(ctx context.Context, modulePaths []string) (lmvs []*internal.LatestModuleVersions, err error) {
	defer derrors.WrapStack(&err, "getMultiLatestModuleVersions(%v)", modulePaths)
	defer stats.Elapsed(ctx, "getMultiLatestModuleVersions")()

	collect := func(rows *sql.Rows) error {
		var (
			modulePath, raw, cooked, good string
			goModBytes                    []byte
		)
		if err := rows.Scan(&modulePath, &raw, &cooked, &good, &goModBytes); err != nil {
			return err
		}
		lmv, err := internal.NewLatestModuleVersions(modulePath, raw, cooked, good, goModBytes)
		if err != nil {
			return err
		}
		lmvs = append(lmvs, lmv)
		return nil
	}

	err = db.db.RunQuery(ctx, `
		SELECT p.path, r.raw_version, r.cooked_version, r.good_version, r.raw_go_mod_bytes
		FROM latest_module_versions r
		INNER JOIN paths p ON p.id = r.module_path_id
		WHERE p.path = ANY($1)
		AND r.status = 200
		ORDER BY p.path DESC
	`, collect, pq.Array(modulePaths))
	if err != nil {
		return nil, err
	}
	return lmvs, nil
}

// getLatestGoodVersion returns the latest version of a module in the modules
// table, respecting the retractions and other information in the given
// LatestModuleVersions. If lmv is nil, it finds the latest version, favoring
// release over pre-release, including incompatible versions, and ignoring
// retractions.
func getLatestGoodVersion(ctx context.Context, tx *database.DB, modulePath string, lmv *internal.LatestModuleVersions) (_ string, err error) {
	defer derrors.WrapStack(&err, "getLatestGoodVersion(%q)", modulePath)

	// Read the versions from the modules table.
	// If the cooked latest version is incompatible, then include
	// incompatible versions. If it isn't, then either there are no
	// incompatible versions, or there are but the latest compatible version
	// has a go.mod file. Either way, ignore incompatible versions.
	q := squirrel.Select("version").
		From("modules").
		Where(squirrel.Eq{"module_path": modulePath}).
		PlaceholderFormat(squirrel.Dollar)
	if lmv != nil && !version.IsIncompatible(lmv.CookedVersion) {
		q = q.Where("NOT incompatible")
	}
	query, args, err := q.ToSql()
	if err != nil {
		return "", err
	}
	vs, err := database.Collect1[string](ctx, tx, query, args...)
	if err != nil {
		return "", err
	}
	// Choose the latest good version from a filtered list of versions.
	if lmv != nil {
		// Remove retracted versions.
		vs = version.RemoveIf(vs, lmv.IsRetracted)
		// The good version should never be later than the cooked version.
		if lmv.CookedVersion != "" {
			vs = version.RemoveIf(vs, func(v string) bool {
				return version.Later(v, lmv.CookedVersion)
			})
		}
	}

	return version.LatestOf(vs), nil
}

// GetLatestModuleVersions returns the row of the latest_module_versions table for modulePath.
// If the module path is not found, it returns nil, nil.
func (db *DB) GetLatestModuleVersions(ctx context.Context, modulePath string) (_ *internal.LatestModuleVersions, err error) {
	lmv, _, err := getLatestModuleVersions(ctx, db.db, modulePath)
	return lmv, err
}

func getLatestModuleVersions(ctx context.Context, db *database.DB, modulePath string) (_ *internal.LatestModuleVersions, id int, err error) {
	defer derrors.WrapStack(&err, "getLatestModuleVersions(%q)", modulePath)

	var (
		raw, cooked, good string
		goModBytes        []byte
		status            int
	)
	err = db.QueryRow(ctx, `
		SELECT
			r.module_path_id, r.raw_version, r.cooked_version, r.good_version, r.raw_go_mod_bytes, r.status
		FROM latest_module_versions r
		INNER JOIN paths p ON p.id = r.module_path_id
		WHERE p.path = $1`,
		modulePath).Scan(&id, &raw, &cooked, &good, &goModBytes, &status)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, 0, nil
		}
		return nil, 0, err
	}
	if status != 200 {
		// No information for this module path, but the ID is still useful.
		return nil, id, nil
	}
	lmv, err := internal.NewLatestModuleVersions(modulePath, raw, cooked, good, goModBytes)
	if err != nil {
		return nil, 0, err
	}
	return lmv, id, nil
}

// rawIsMoreRecent reports whether raw version v1 is more recent than v2.
// v1 is more recent if it is later according to the go command (higher semver,
// preferring release to prerelease). However, the raw latest version can go
// backwards if it was an incompatible version, but then a compatible version
// with a go.mod file is published. For example, the module starts with a
// v2.0.0+incompatible, but then the author adds a v1.0.0 with a go.mod file,
// making v1.0.0 the new latest.
func rawIsMoreRecent(v1, v2 string) bool {
	return version.Later(v1, v2) || (version.IsIncompatible(v2) && !version.IsIncompatible(v1))
}

// UpdateLatestModuleVersions upserts its argument into the latest_module_versions table
// if the row doesn't exist, or the new version is later.
// It returns the version that is in the DB when it completes.
func (db *DB) UpdateLatestModuleVersions(ctx context.Context, vNew *internal.LatestModuleVersions) (_ *internal.LatestModuleVersions, err error) {
	defer derrors.WrapStack(&err, "UpdateLatestModuleVersions(%q)", vNew.ModulePath)

	var vResult *internal.LatestModuleVersions
	// We need RepeatableRead here because the INSERT...ON CONFLICT does a read.
	err = db.db.Transact(ctx, sql.LevelRepeatableRead, func(tx *database.DB) error {
		vCur, id, err := getLatestModuleVersions(ctx, tx, vNew.ModulePath)
		if err != nil {
			return err
		}
		// Is vNew the most recent information, or does the DB already have
		// something more up to date?
		update := vCur == nil || rawIsMoreRecent(vNew.RawVersion, vCur.RawVersion) ||
			// If new versions are added, cooked can change even if raw is the same.
			(vNew.RawVersion == vCur.RawVersion && vNew.CookedVersion != vCur.CookedVersion)
		if !update {
			log.Debugf(ctx, "%s: not updating latest module versions", vNew.ModulePath)
			vResult = vCur
			return nil
		}
		if vCur == nil {
			log.Debugf(ctx, "%s: inserting latest_module_versions raw=%q, cooked=%q",
				vNew.ModulePath, vNew.RawVersion, vNew.CookedVersion)
		} else {
			log.Debugf(ctx, "%s: updating latest_module_versions raw=%q, cooked=%q to raw=%q, cooked=%q",
				vNew.ModulePath, vCur.RawVersion, vCur.CookedVersion,
				vNew.RawVersion, vNew.CookedVersion)
			// If the latest good version is now retracted, recompute it.
			if vCur.GoodVersion != "" && vNew.IsRetracted(vCur.GoodVersion) {
				good, err := getLatestGoodVersion(ctx, tx, vNew.ModulePath, vNew)
				if err != nil {
					return err
				}
				vNew.GoodVersion = good
				log.Debugf(ctx, "%s: updating latest_module_versions good=%q", vNew.ModulePath, vNew.GoodVersion)
			} else {
				vNew.GoodVersion = vCur.GoodVersion
			}
		}
		vResult = vNew
		return upsertLatestModuleVersions(ctx, tx, vNew.ModulePath, id, vNew, 200)
	})
	if err != nil {
		return nil, err
	}
	return vResult, nil
}

// UpdateLatestModuleVersionsStatus updates or inserts a failure status into the
// latest_module_versions table.
// It only updates the table if it doesn't have valid information for the module path.
func (db *DB) UpdateLatestModuleVersionsStatus(ctx context.Context, modulePath string, newStatus int) (err error) {
	defer derrors.WrapStack(&err, "UpdateLatestModuleVersionsStatus(%q, %d)", modulePath, newStatus)

	// We need RepeatableRead here because the INSERT...ON CONFLICT does a read.
	return db.db.Transact(ctx, sql.LevelRepeatableRead, func(tx *database.DB) error {
		var id, curStatus int
		err := tx.QueryRow(ctx, `
				SELECT r.module_path_id, r.status
				FROM latest_module_versions r
				INNER JOIN paths p ON p.id = r.module_path_id
				WHERE p.path = $1`,
			modulePath).Scan(&id, &curStatus)
		if err != nil && err != sql.ErrNoRows {
			return err
		}
		if curStatus == 200 {
			return nil
		}
		log.Debugf(ctx, "%s: updating latest_module_versions status to %d", modulePath, newStatus)
		return upsertLatestModuleVersions(ctx, tx, modulePath, id, nil, newStatus)
	})
}

func upsertLatestModuleVersions(ctx context.Context, tx *database.DB, modulePath string, id int, lmv *internal.LatestModuleVersions, status int) (err error) {
	defer derrors.WrapStack(&err, "upsertLatestModuleVersions(%s, %d)", modulePath, status)

	// If the row doesn't exist, get a path ID for the module path.
	if id == 0 {
		id, err = upsertPath(ctx, tx, modulePath)
		if err != nil {
			return err
		}
	}
	var (
		raw, cooked, good string
		goModBytes        = []byte{} // not nil, a zero-length slice
		deprecated        bool
	)
	if lmv != nil {
		raw = lmv.RawVersion
		cooked = lmv.CookedVersion
		good = lmv.GoodVersion
		deprecated = lmv.Deprecated
		// Convert the go.mod file into bytes.
		goModBytes, err = lmv.GoModFile.Format()
		if err != nil {
			return err
		}
	}
	_, err = tx.Exec(ctx, `
		INSERT INTO latest_module_versions (
			module_path_id,
			series_path,
			raw_version,
			cooked_version,
			good_version,
			deprecated,
			raw_go_mod_bytes,
			status
		) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
		ON CONFLICT (module_path_id)
		DO UPDATE SET
			series_path=excluded.series_path,
			raw_version=excluded.raw_version,
			cooked_version=excluded.cooked_version,
			good_version=excluded.good_version,
			deprecated=excluded.deprecated,
			raw_go_mod_bytes=excluded.raw_go_mod_bytes,
			status=excluded.status
		`,
		id, internal.SeriesPathForModule(modulePath), raw, cooked, good, deprecated, goModBytes, status)
	return err
}

// UpdateLatestGoodVersion updates the latest version of modulePath.
func (db *DB) UpdateLatestGoodVersion(ctx context.Context, modulePath string) error {
	return db.db.Transact(ctx, sql.LevelRepeatableRead, func(tx *database.DB) error {
		latest, err := getLatestGoodVersion(ctx, tx, modulePath, nil)
		if err != nil {
			return err
		}
		return updateLatestGoodVersion(ctx, tx, modulePath, latest)
	})
}

// updateLatestGoodVersion updates latest_module_versions.good_version for modulePath to version.
func updateLatestGoodVersion(ctx context.Context, tx *database.DB, modulePath, version string) (err error) {
	defer derrors.WrapStack(&err, "updateLatestGoodVersion(%q, %q)", modulePath, version)

	n, err := tx.Exec(ctx, `
		UPDATE latest_module_versions
		SET good_version = $2
		WHERE module_path_id = (
			SELECT id FROM paths
			WHERE path = $1
		)`, modulePath, version)
	if err != nil {
		return err
	}
	switch n {
	case 0:
		log.Debugf(ctx, "updateLatestGoodVersion(%q, %q): no change", modulePath, version)
	case 1:
		log.Debugf(ctx, "updateLatestGoodVersion(%q, %q): updated", modulePath, version)
	default:
		return errors.New("more than one row affected")
	}
	return nil
}
