// 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"
	"fmt"
	"strings"

	"github.com/lib/pq"
	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/stdlib"
)

// GetPathInfo returns information about the "best" entity (module, path or directory) with
// the given path. The module and version arguments provide additional constraints.
// If the module is unknown, pass internal.UnknownModulePath; if the version is unknown, pass
// internal.LatestVersion.
//
// The rules for picking the best are:
// 1. Match the module path and or version, if they are provided;
// 2. Prefer newer module versions to older, and release to pre-release;
// 3. In the unlikely event of two paths at the same version, pick the longer module path.
func (db *DB) GetPathInfo(ctx context.Context, path, inModulePath, inVersion string) (outModulePath, outVersion string, isPackage bool, err error) {
	defer derrors.Wrap(&err, "DB.GetPathInfo(ctx, %q, %q, %q)", path, inModulePath, inVersion)

	var constraints []string
	args := []interface{}{path}
	if inModulePath != internal.UnknownModulePath {
		constraints = append(constraints, fmt.Sprintf("AND m.module_path = $%d", len(args)+1))
		args = append(args, inModulePath)
	}
	if inVersion != internal.LatestVersion {
		constraints = append(constraints, fmt.Sprintf("AND m.version = $%d", len(args)+1))
		args = append(args, inVersion)
	}
	query := fmt.Sprintf(`
		SELECT m.module_path, m.version, p.name != ''
		FROM paths p
		INNER JOIN modules m ON (p.module_id = m.id)
		WHERE p.path = $1
		%s
		ORDER BY
			m.version_type = 'release' DESC,
			m.sort_version DESC,
			m.module_path DESC
		LIMIT 1
	`, strings.Join(constraints, " "))
	err = db.db.QueryRow(ctx, query, args...).Scan(&outModulePath, &outVersion, &isPackage)
	switch err {
	case sql.ErrNoRows:
		return "", "", false, derrors.NotFound
	case nil:
		return outModulePath, outVersion, isPackage, nil
	default:
		return "", "", false, err
	}
}

type dbPath struct {
	id              int64
	path            string
	moduleID        int64
	v1Path          string
	name            string
	licenseTypes    []string
	licensePaths    []string
	redistributable bool
}

func (db *DB) getPathsInModule(ctx context.Context, modulePath, version string) (_ []*dbPath, err error) {
	defer derrors.Wrap(&err, "DB.getPathsInModule(ctx, %q, %q)", modulePath, version)
	query := `
	SELECT
		p.id,
		p.path,
		p.module_id,
		p.v1_path,
		p.name,
		p.license_types,
		p.license_paths,
		p.redistributable
	FROM
		paths p
	INNER JOIN
		modules m
	ON
		p.module_id = m.id
	WHERE
		m.module_path = $1
		AND m.version = $2
	ORDER BY path;`

	var paths []*dbPath
	collect := func(rows *sql.Rows) error {
		var p dbPath
		if err := rows.Scan(&p.id, &p.path, &p.moduleID, &p.v1Path, &p.name, pq.Array(&p.licenseTypes),
			pq.Array(&p.licensePaths), &p.redistributable); err != nil {
			return fmt.Errorf("row.Scan(): %v", err)
		}
		paths = append(paths, &p)
		return nil
	}
	if err := db.db.RunQuery(ctx, query, collect, modulePath, version); err != nil {
		return nil, err
	}
	return paths, nil
}

// GetStdlibPathsWithSuffix returns information about all paths in the latest version of the standard
// library whose last component is suffix. A path that exactly match suffix is not included;
// the path must end with "/" + suffix.
//
// We are only interested in actual standard library packages: not commands, which we happen to include
// in the stdlib module, and not directories (paths that do not contain a package).
func (db *DB) GetStdlibPathsWithSuffix(ctx context.Context, suffix string) (paths []string, err error) {
	defer derrors.Wrap(&err, "DB.GetStdlibPaths(ctx, %q)", suffix)

	q := `
		SELECT path
		FROM paths
		WHERE module_id = (
			-- latest release version of stdlib
			SELECT id
			FROM modules
			WHERE module_path = $1
			ORDER BY
				version_type = 'release' DESC,
				sort_version DESC
			LIMIT 1)
			AND name != ''
			AND path NOT LIKE 'cmd/%'
			AND path LIKE '%/' || $2
		ORDER BY path
	`
	err = db.db.RunQuery(ctx, q, func(rows *sql.Rows) error {
		var p string
		if err := rows.Scan(&p); err != nil {
			return err
		}
		paths = append(paths, p)
		return nil
	}, stdlib.ModulePath, suffix)
	if err != nil {
		return nil, err
	}
	return paths, nil
}
