// 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"
	"errors"
	"fmt"
	"net/http"
	"sort"
	"strings"

	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/licenses"
	"golang.org/x/pkgsite/internal/postgres"
	"golang.org/x/pkgsite/internal/stdlib"
)

// DirectoryPage contains data needed to generate a directory template.
type DirectoryPage struct {
	basePage
	*Directory
}

// DirectoryHeader contains information for the header on a directory page.
type DirectoryHeader struct {
	Module
	Path string
	URL  string
}

// Directory contains information for an individual directory.
type Directory struct {
	DirectoryHeader
	Packages []*Package
}

// serveDirectoryPage serves a directory view for a directory in a module
// version.
func (s *Server) serveDirectoryPage(ctx context.Context, w http.ResponseWriter, r *http.Request, ds internal.DataSource, vdir *internal.VersionedDirectory, requestedVersion string) (err error) {
	defer derrors.Wrap(&err, "serveDirectoryPage for %s@%s", vdir.Path, requestedVersion)
	tab := r.FormValue("tab")
	settings, ok := directoryTabLookup[tab]
	if tab == "" || !ok || settings.Disabled {
		tab = "subdirectories"
		settings = directoryTabLookup[tab]
	}
	header := createDirectoryHeader(vdir.Path, &vdir.ModuleInfo, vdir.Licenses)
	if requestedVersion == internal.LatestVersion {
		header.URL = constructDirectoryURL(vdir.Path, vdir.ModulePath, internal.LatestVersion)
	}
	details, err := fetchDetailsForDirectory(r, tab, ds, vdir)
	if err != nil {
		return err
	}
	page := &DetailsPage{
		basePage:       s.newBasePage(r, fmt.Sprintf("%s directory", vdir.Path)),
		Name:           vdir.Path,
		Settings:       settings,
		Header:         header,
		Breadcrumb:     breadcrumbPath(vdir.Path, vdir.ModulePath, linkVersion(vdir.Version, vdir.ModulePath)),
		Details:        details,
		CanShowDetails: true,
		Tabs:           directoryTabSettings,
		PageType:       pageTypeDirectory,
	}
	s.servePage(ctx, w, settings.TemplateName, page)
	return nil
}

func (s *Server) legacyServeDirectoryPage(ctx context.Context, w http.ResponseWriter, r *http.Request, ds internal.DataSource, dbDir *internal.LegacyDirectory, requestedVersion string) (err error) {
	defer derrors.Wrap(&err, "legacyServeDirectoryPage for %s@%s", dbDir.Path, requestedVersion)
	tab := r.FormValue("tab")
	settings, ok := directoryTabLookup[tab]
	if tab == "" || !ok || settings.Disabled {
		tab = "subdirectories"
		settings = directoryTabLookup[tab]
	}
	licenses, err := ds.LegacyGetModuleLicenses(ctx, dbDir.ModulePath, dbDir.Version)
	if err != nil {
		return err
	}
	header, err := legacyCreateDirectory(dbDir, licensesToMetadatas(licenses), false)
	if err != nil {
		return err
	}
	if requestedVersion == internal.LatestVersion {
		header.URL = constructDirectoryURL(dbDir.Path, dbDir.ModulePath, internal.LatestVersion)
	}

	details, err := legacyFetchDetailsForDirectory(r, tab, dbDir, licenses)
	if err != nil {
		return err
	}
	page := &DetailsPage{
		basePage:       s.newBasePage(r, fmt.Sprintf("%s directory", dbDir.Path)),
		Name:           dbDir.Path,
		Settings:       settings,
		Header:         header,
		Breadcrumb:     breadcrumbPath(dbDir.Path, dbDir.ModulePath, linkVersion(dbDir.Version, dbDir.ModulePath)),
		Details:        details,
		CanShowDetails: true,
		Tabs:           directoryTabSettings,
		PageType:       pageTypeDirectory,
	}
	s.servePage(ctx, w, settings.TemplateName, page)
	return nil
}

// fetchDirectoryDetails fetches data for the directory specified by path and
// version from the database and returns a Directory.
//
// includeDirPath indicates whether a package is included if its import path is
// the same as dirPath.
// This argument is needed because on the module "Packages" tab, we want to
// display all packages in the module, even if the import path is the same as
// the module path. However, on the package and directory view's
// "Subdirectories" tab, we do not want to include packages whose import paths
// are the same as the dirPath.
func fetchDirectoryDetails(ctx context.Context, ds internal.DataSource, vdir *internal.VersionedDirectory, includeDirPath bool) (_ *Directory, err error) {
	defer derrors.Wrap(&err, "fetchDirectoryDetails(%q, %q, %q, %v)",
		vdir.Path, vdir.ModulePath, vdir.Version, vdir.Licenses)

	db, ok := ds.(*postgres.DB)
	if !ok {
		return nil, proxydatasourceNotSupportedErr()
	}
	if includeDirPath && vdir.Path != vdir.ModulePath && vdir.Path != stdlib.ModulePath {
		return nil, fmt.Errorf("includeDirPath can only be set to true if dirPath = modulePath: %w", derrors.InvalidArgument)
	}
	packages, err := db.GetPackagesInDirectory(ctx, vdir.Path, vdir.ModulePath, vdir.Version)
	if err != nil {
		if !errors.Is(err, derrors.NotFound) {
			return nil, err
		}
		header := createDirectoryHeader(vdir.Path, &vdir.ModuleInfo, vdir.Licenses)
		return &Directory{DirectoryHeader: *header}, nil
	}
	return createDirectory(vdir.Path, &vdir.ModuleInfo, packages, vdir.Licenses, includeDirPath)
}

// legacyFetchDirectoryDetails fetches data for the directory specified by path and
// version from the database and returns a Directory.
//
// includeDirPath indicates whether a package is included if its import path is
// the same as dirPath.
// This argument is needed because on the module "Packages" tab, we want to
// display all packages in the module, even if the import path is the same as
// the module path. However, on the package and directory view's
// "Subdirectories" tab, we do not want to include packages whose import paths
// are the same as the dirPath.
func legacyFetchDirectoryDetails(ctx context.Context, ds internal.DataSource, dirPath string, mi *internal.ModuleInfo,
	licmetas []*licenses.Metadata, includeDirPath bool) (_ *Directory, err error) {
	defer derrors.Wrap(&err, "legacyfetchDirectoryDetails(%q, %q, %q, %v)", dirPath, mi.ModulePath, mi.Version, licmetas)

	if includeDirPath && dirPath != mi.ModulePath && dirPath != stdlib.ModulePath {
		return nil, fmt.Errorf("includeDirPath can only be set to true if dirPath = modulePath: %w", derrors.InvalidArgument)
	}

	if dirPath == stdlib.ModulePath {
		pkgs, err := ds.LegacyGetPackagesInModule(ctx, stdlib.ModulePath, mi.Version)
		if err != nil {
			return nil, err
		}
		return legacyCreateDirectory(&internal.LegacyDirectory{
			LegacyModuleInfo: internal.LegacyModuleInfo{ModuleInfo: *mi},
			Path:             dirPath,
			Packages:         pkgs,
		}, licmetas, includeDirPath)
	}

	dbDir, err := ds.LegacyGetDirectory(ctx, dirPath, mi.ModulePath, mi.Version, internal.AllFields)
	if errors.Is(err, derrors.NotFound) {
		return legacyCreateDirectory(&internal.LegacyDirectory{
			LegacyModuleInfo: internal.LegacyModuleInfo{ModuleInfo: *mi},
			Path:             dirPath,
			Packages:         nil,
		}, licmetas, includeDirPath)
	}
	if err != nil {
		return nil, err
	}
	return legacyCreateDirectory(dbDir, licmetas, includeDirPath)
}

// legacyCreateDirectory constructs a *Directory for the given dirPath.
func legacyCreateDirectory(dbDir *internal.LegacyDirectory, licmetas []*licenses.Metadata, includeDirPath bool) (_ *Directory, err error) {
	defer derrors.Wrap(&err, "legacyCreateDirectory(%q, %q, %t)", dbDir.Path, dbDir.Version, includeDirPath)
	var packages []*internal.PackageMeta
	for _, pkg := range dbDir.Packages {
		newPkg := internal.PackageMetaFromLegacyPackage(pkg)
		packages = append(packages, newPkg)
	}
	return createDirectory(dbDir.Path, &dbDir.ModuleInfo, packages, licmetas, includeDirPath)
}

// createDirectory constructs a *Directory for the given dirPath.
//
// includeDirPath indicates whether a package is included if its import path is
// the same as dirPath.
// This argument is needed because on the module "Packages" tab, we want to
// display all packages in the mdoule, even if the import path is the same as
// the module path. However, on the package and directory view's
// "Subdirectories" tab, we do not want to include packages whose import paths
// are the same as the dirPath.
func createDirectory(dirPath string, mi *internal.ModuleInfo, pkgMetas []*internal.PackageMeta,
	licmetas []*licenses.Metadata, includeDirPath bool) (_ *Directory, err error) {
	var packages []*Package
	for _, pm := range pkgMetas {
		if !includeDirPath && pm.Path == dirPath {
			continue
		}
		newPkg, err := createPackage(pm, mi, false)
		if err != nil {
			return nil, err
		}
		newPkg.PathAfterDirectory = internal.Suffix(pm.Path, dirPath)
		if newPkg.PathAfterDirectory == "" {
			newPkg.PathAfterDirectory = effectiveName(pm.Path, pm.Name) + " (root)"
		}
		packages = append(packages, newPkg)
	}
	sort.Slice(packages, func(i, j int) bool { return packages[i].Path < packages[j].Path })
	header := createDirectoryHeader(dirPath, mi, licmetas)

	return &Directory{
		DirectoryHeader: *header,
		Packages:        packages,
	}, nil
}

func createDirectoryHeader(dirPath string, mi *internal.ModuleInfo, licmetas []*licenses.Metadata) (_ *DirectoryHeader) {
	mod := createModule(mi, licmetas, false)
	return &DirectoryHeader{
		Module: *mod,
		Path:   dirPath,
		URL:    constructDirectoryURL(dirPath, mi.ModulePath, linkVersion(mi.Version, mi.ModulePath)),
	}
}

func constructDirectoryURL(dirPath, modulePath, linkVersion string) string {
	if linkVersion == internal.LatestVersion {
		return fmt.Sprintf("/%s", dirPath)
	}
	if dirPath == modulePath || modulePath == stdlib.ModulePath {
		return fmt.Sprintf("/%s@%s", dirPath, linkVersion)
	}
	return fmt.Sprintf("/%s@%s/%s", modulePath, linkVersion, strings.TrimPrefix(dirPath, modulePath+"/"))
}
