package imports

import (
	"context"
	"strings"
	"testing"

	"github.com/stretchr/testify/assert"
	"go.skia.org/infra/go/testutils"
	"go.skia.org/infra/go/util"
)

// Any package named testutil(s) and the packages in the following list are
// allowed to import other test packages, but non-test packages are not allowed
// to import them.
var testPackages = []string{
	"github.com/stretchr/testify/assert",
	"github.com/stretchr/testify/require",
	"go.skia.org/infra/go/deepequal/assertdeep",
	"go.skia.org/infra/go/git/testutils/mem_git",
	"go.skia.org/infra/go/mockhttpclient",
	"go.skia.org/infra/golden/go/mocks",
	"go.skia.org/infra/golden/go/ingestion/mocks",
	"go.skia.org/infra/task_scheduler/go/scheduling/perftest",
	"testing",
	"go.skia.org/infra/perf/go/shortcut/shortcuttest",
	"go.skia.org/infra/perf/go/sql/sqltest",
	"go.skia.org/infra/perf/go/alerts/alertstest",
	"go.skia.org/infra/perf/go/regression/regressiontest",
	"go.skia.org/infra/perf/go/git/gittest",
	"go.skia.org/infra/golden/go/sql/sqltest",
	"go.skia.org/infra/go/gcs/test_gcsclient",
}

// TODO(borenet): this list should be empty.
// items should not be added to this list, only removed.
var legacyTestImportExceptions = map[string][]string{
	"go.skia.org/infra/task_driver/go/td": {
		"github.com/stretchr/testify/require",
	},
	"go.skia.org/infra/task_scheduler/go/db": {
		"github.com/stretchr/testify/require",
		"go.skia.org/infra/go/deepequal/assertdeep",
		"go.skia.org/infra/go/git/testutils",
		"go.skia.org/infra/go/testutils",
	},
	"go.skia.org/infra/task_scheduler/go/task_scheduler": {
		"go.skia.org/infra/task_scheduler/go/testutils",
	},
	"go.skia.org/infra/task_scheduler/go/tryjobs": {
		"github.com/stretchr/testify/require",
		"go.skia.org/infra/go/depot_tools/testutils",
		"go.skia.org/infra/go/git/testutils",
		"go.skia.org/infra/go/mockhttpclient",
		"go.skia.org/infra/go/testutils",
		"go.skia.org/infra/task_scheduler/go/task_cfg_cache/testutils",
		"go.skia.org/infra/go/buildbucket/mocks",
		"go.skia.org/infra/go/cas/mocks",
	},
}

// isTestPackage returns true if the given package should be considered a test
// package, ie. it is allowed to import other test packages and non-test
// packages are not allowed to import it.
func isTestPackage(pkg string) bool {
	return strings.HasSuffix(pkg, "shared_tests") ||
		strings.HasSuffix(pkg, "testutil") ||
		strings.HasSuffix(pkg, "testutils") ||
		strings.HasSuffix(pkg, "mocks") ||
		util.In(pkg, testPackages)
}

// testImportAllowed returns true if the given non-test package is allowed
// to import the given test package.
func testImportAllowed(importer, importee string) bool {
	return util.In(importee, legacyTestImportExceptions[importer])
}

// TestImports verifies that we follow some basic rules for imports:
// 1. No non-test package imports a test package, with the exception of those
//    listed in legacyTestImportExceptions.
// 2. No packages use CGO.
//
// These checks are combined into one test because LoadAllPackageData is slow.
func TestImports(t *testing.T) {

	// For compatibility with Bazel: the "go" command fails if HOME is not set.
	testutils.SetUpFakeHomeDir(t, "imports_test")

	// Find all packages, categorize as test and non-test.
	pkgs, err := LoadAllPackageData(context.Background())
	assert.NoError(t, err)
	testPkgs := make(map[string]*Package, len(pkgs))
	nonTestPkgs := make(map[string]*Package, len(pkgs))
	for name, pkg := range pkgs {
		if isTestPackage(name) {
			testPkgs[name] = pkg
		} else {
			nonTestPkgs[name] = pkg
		}
	}
	for _, name := range testPackages {
		testPkgs[name] = &Package{} // Not actually used.
	}

	// 1. Ensure that no non-test package imports a test package.
	for name, pkg := range nonTestPkgs {
		for _, imported := range pkg.Imports {
			_, importsTestPkg := testPkgs[imported]
			// TODO: Remove this once legacyTestImportExceptions is empty.
			if importsTestPkg && testImportAllowed(name, imported) {
				importsTestPkg = false
			}
			assert.Falsef(t, importsTestPkg, "Non-test package %s imports test package %s", name, imported)
		}
		// Verify that legacyTestImportExceptions doesn't contain more
		// entries than it should.
		// TODO: Remove this once legacyTestImportExceptions is empty.
		for _, allowedTestImport := range legacyTestImportExceptions[name] {
			assert.Truef(t, util.In(allowedTestImport, pkg.Imports), "Non-test package %s is allowed to import %s but does not.", name, allowedTestImport)
		}
	}

	// 2. Ensure that no package uses CGO.
	for name, pkg := range pkgs {
		for _, imp := range pkg.Imports {
			assert.NotEqual(t, "C", imp, "Package %s uses CGO.", name)
		}
	}
}
