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

import (
	"archive/zip"
	"context"
	"net/http"
	"sort"
	"strings"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/google/safehtml"
	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/licenses"
	"golang.org/x/pkgsite/internal/log"
	"golang.org/x/pkgsite/internal/proxy"
	"golang.org/x/pkgsite/internal/stdlib"
)

var testProxyCommitTime = time.Date(2019, 1, 30, 0, 0, 0, 0, time.UTC)

func cleanFetchResult(fr *FetchResult, detector *licenses.Detector) *FetchResult {
	fr.ModulePath = fr.Module.ModulePath
	if fr.GoModPath == "" {
		fr.GoModPath = fr.ModulePath
	}
	if fr.Status == 0 {
		fr.Status = 200
	}
	if fr.Module.Version == "" {
		fr.Module.Version = "v1.0.0"
	}
	if fr.RequestedVersion == "" {
		fr.RequestedVersion = fr.Module.Version
	}
	fr.ResolvedVersion = fr.Module.Version
	if fr.Module.CommitTime.IsZero() {
		fr.Module.CommitTime = testProxyCommitTime
	}

	allLicenses := detector.AllLicenses()
	if len(allLicenses) > 0 {
		fr.Module.Licenses = allLicenses
		fr.Module.IsRedistributable = true
		for _, d := range fr.Module.Units {
			isRedist, lics := detector.PackageInfo(internal.Suffix(d.Path, fr.ModulePath))
			for _, l := range lics {
				d.Licenses = append(d.Licenses, l.Metadata)
			}
			d.IsRedistributable = isRedist
		}
	}

	shouldSetPVS := (fr.PackageVersionStates == nil)
	for _, u := range fr.Module.Units {
		u.UnitMeta = internal.UnitMeta{
			ModulePath:        fr.Module.ModulePath,
			Version:           fr.Module.Version,
			Path:              u.Path,
			Name:              u.Name,
			IsRedistributable: u.IsRedistributable,
			Licenses:          u.Licenses,
		}
		if u.Documentation != nil {
			if u.Documentation.GOOS == "" {
				u.Documentation.GOOS = "linux"
				u.Documentation.GOARCH = "amd64"
			}
		}
		if u.IsPackage() {
			fr.Module.LegacyPackages = append(fr.Module.LegacyPackages, &internal.LegacyPackage{
				Path:              u.Path,
				Licenses:          u.Licenses,
				V1Path:            internal.V1Path(u.Path, u.ModulePath),
				Name:              u.Name,
				Synopsis:          u.Documentation.Synopsis,
				DocumentationHTML: u.Documentation.HTML,
				Imports:           u.Imports,
				GOOS:              u.Documentation.GOOS,
				GOARCH:            u.Documentation.GOARCH,
				IsRedistributable: u.IsRedistributable,
			})
			if shouldSetPVS {
				fr.PackageVersionStates = append(
					fr.PackageVersionStates, &internal.PackageVersionState{
						PackagePath: u.Path,
						ModulePath:  fr.Module.ModulePath,
						Version:     fr.Module.Version,
						Status:      http.StatusOK,
					},
				)
			}
		}
	}
	return fr
}

func licenseDetector(ctx context.Context, t *testing.T, modulePath, version string, proxyClient *proxy.Client) *licenses.Detector {
	t.Helper()
	var (
		zipReader *zip.Reader
		err       error
	)
	if modulePath == stdlib.ModulePath {
		zipReader, _, err = stdlib.Zip(version)
		if err != nil {
			t.Fatal(err)
		}
	} else {
		zipReader, err = proxyClient.GetZip(ctx, modulePath, version)
		if err != nil {
			t.Fatal(err)
		}
	}
	logf := func(format string, args ...interface{}) {
		log.Infof(ctx, format, args...)
	}
	return licenses.NewDetector(modulePath, version, zipReader, logf)
}

func sortFetchResult(fr *FetchResult) {
	sort.Slice(fr.Module.LegacyPackages, func(i, j int) bool {
		return fr.Module.LegacyPackages[i].Path < fr.Module.LegacyPackages[j].Path
	})
	sort.Slice(fr.Module.Units, func(i, j int) bool {
		return fr.Module.Units[i].Path < fr.Module.Units[j].Path
	})
	sort.Slice(fr.Module.Licenses, func(i, j int) bool {
		return fr.Module.Licenses[i].FilePath < fr.Module.Licenses[j].FilePath
	})
	sort.Slice(fr.PackageVersionStates, func(i, j int) bool {
		return fr.PackageVersionStates[i].PackagePath < fr.PackageVersionStates[j].PackagePath
	})
	for _, dir := range fr.Module.Units {
		sort.Slice(dir.Licenses, func(i, j int) bool {
			return dir.Licenses[i].FilePath < dir.Licenses[j].FilePath
		})
	}
	for _, pkg := range fr.Module.LegacyPackages {
		sort.Slice(pkg.Licenses, func(i, j int) bool {
			return pkg.Licenses[i].FilePath < pkg.Licenses[j].FilePath
		})
	}
}

// validateDocumentationHTML checks that the doc HTML contains a set of
// substrings. The desired strings consist of the "want" module's documentation
// fields, with multiple substrings separated by '~'.
func validateDocumentationHTML(t *testing.T, got, want *internal.Module) {
	t.Helper()
	defer func() {
		if r := recover(); r != nil {
			t.Fatalf("Recovered in checkDocumentationHTML: %v \n; diff = %s", r, cmp.Diff(want, got))
		}
	}()

	checkHTML := func(msg string, i int, hGot, hWant safehtml.HTML) {
		t.Helper()
		got := hGot.String()
		// Treat the wanted DocumentationHTML as a set of substrings to look for, separated by ~.
		for _, want := range strings.Split(hWant.String(), "~") {
			want = strings.TrimSpace(want)
			if !strings.Contains(got, want) {
				t.Errorf("doc for %s[%d]:\nmissing %q; got\n%q", msg, i, want, got)
			}
		}
	}

	for i := 0; i < len(want.LegacyPackages); i++ {
		checkHTML("LegacyPackages", i, got.LegacyPackages[i].DocumentationHTML, want.LegacyPackages[i].DocumentationHTML)
	}
	for i := 0; i < len(want.Units); i++ {
		if !want.Units[i].IsPackage() {
			continue
		}
		checkHTML("Directories", i, got.Units[i].Documentation.HTML, want.Units[i].Documentation.HTML)
	}
}
