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

import (
	"context"
	"strings"

	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/log"
	"golang.org/x/pkgsite/internal/stdlib"
	"golang.org/x/text/language"
	"golang.org/x/text/message"
)

// ImportsDetails contains information for a package's imports.
type ImportsDetails struct {
	ModulePath string

	// ExternalImports is the collection of package imports that are not in
	// the Go standard library and are not part of the same module
	ExternalImports []string

	// InternalImports is an array of packages representing the package's
	// imports that are part of the same module.
	InternalImports []string

	// StdLib is an array of packages representing the package's imports
	// that are in the Go standard library.
	StdLib []string
}

// fetchImportsDetails fetches imports for the package version specified by
// pkgPath, modulePath and version from the database and returns a ImportsDetails.
func fetchImportsDetails(ctx context.Context, ds internal.DataSource, pkgPath, modulePath, resolvedVersion string) (_ *ImportsDetails, err error) {
	u, err := ds.GetUnit(ctx, &internal.UnitMeta{
		Path: pkgPath,
		ModuleInfo: internal.ModuleInfo{
			ModulePath: modulePath,
			Version:    resolvedVersion,
		},
	}, internal.WithImports, internal.BuildContext{})
	if err != nil {
		return nil, err
	}

	var externalImports, moduleImports, std []string
	for _, p := range u.Imports {
		if stdlib.Contains(p) {
			std = append(std, p)
		} else if strings.HasPrefix(p+"/", modulePath+"/") {
			moduleImports = append(moduleImports, p)
		} else {
			externalImports = append(externalImports, p)
		}
	}

	return &ImportsDetails{
		ModulePath:      modulePath,
		ExternalImports: externalImports,
		InternalImports: moduleImports,
		StdLib:          std,
	}, nil
}

// ImportedByDetails contains information for the collection of packages that
// import a given package.
type ImportedByDetails struct {
	// ModulePath is the module path for the package referenced on this page.
	ModulePath string

	// ImportedBy is the collection of packages that import the
	// given package and are not part of the same module.
	// They are organized into a tree of sections by prefix.
	ImportedBy []*Section

	// NumImportedByDisplay is the display text at the top of the imported by
	// tab section, which shows the imported by count and package limit.
	NumImportedByDisplay string

	// Total is the total number of importers.
	Total int
}

var (
	// importedByLimit is the maximum number of importers displayed on the imported
	// by page.
	// Variable for testing.
	importedByLimit = 20001
)

// fetchImportedByDetails fetches importers for the package version specified by
// path and version from the database and returns a ImportedByDetails.
func fetchImportedByDetails(ctx context.Context, ds internal.DataSource, pkgPath, modulePath string) (*ImportedByDetails, error) {
	db, ok := ds.(internal.PostgresDB)
	if !ok {
		// The proxydatasource does not support the imported by page.
		return nil, datasourceNotSupportedErr()
	}

	importedBy, err := db.GetImportedBy(ctx, pkgPath, modulePath, importedByLimit)
	if err != nil {
		return nil, err
	}
	numImportedBy := len(importedBy)
	numImportedBySearch, err := db.GetImportedByCount(ctx, pkgPath, modulePath)
	if err != nil {
		return nil, err
	}
	if numImportedBy < importedByLimit && numImportedBySearch > numImportedBy {
		// Unless we hit the limit, numImportedBySearch should never be greater
		// than numImportedBy. If that happens, log an error so that we can
		// debug, but continue with generating the page fo the user.
		log.Errorf(ctx, "pkg %q, module %q: search_documents.num_imported_by %d > numImportedBy %d from imports unique, which shouldn't happen",
			pkgPath, modulePath, numImportedBySearch, numImportedBy)
	}

	if numImportedBy >= importedByLimit {
		importedBy = importedBy[:importedByLimit-1]
	}
	sections := Sections(importedBy, nextPrefixAccount)

	// Display the number of importers, taking into account the number we
	// actually retrieved, the limit on that number, and the imported-by count
	// in the search_documents table.
	pr := message.NewPrinter(language.English)
	var (
		display string
		pkgword = "package"
	)
	if numImportedBy > 1 {
		pkgword = "packages"
	}
	switch {
	// If there are more importers than the limit, and the search number is
	// greater, use the search number and indicate that we're displaying fewer.
	case numImportedBy >= importedByLimit && numImportedBySearch > numImportedBy:
		display = pr.Sprintf("%d (displaying %d %s)", numImportedBySearch, importedByLimit-1, pkgword)
	// If we've exceeded the limit but the search number is smaller, we don't
	// know the true number, so say so.
	case numImportedBy >= importedByLimit:
		display = pr.Sprintf("%d (displaying more than %d %s, including internal and invalid packages)", numImportedBySearch, importedByLimit-1, pkgword)
	// If we haven't exceeded the limit and we have more than the search number,
	// then display both numbers so users coming from the search page won't see
	// a mismatch.
	case numImportedBy > numImportedBySearch:
		display = pr.Sprintf("%d (displaying %d %s, including internal and invalid packages)", numImportedBySearch, numImportedBy, pkgword)
	// Otherwise, we have all the packages, and the search number is either
	// wrong (perhaps it hasn't been recomputed yet) or it is the same as the
	// retrieved number. In that case, just display the retrieved number.
	default:
		display = pr.Sprint(numImportedBy)
	}
	return &ImportedByDetails{
		ModulePath:           modulePath,
		ImportedBy:           sections,
		NumImportedByDisplay: display,
		Total:                numImportedBy,
	}, nil
}
