package updater

import (
	"context"
	"fmt"
	"path/filepath"

	"github.com/bazelbuild/buildtools/build"
	"github.com/bazelbuild/buildtools/edit"
	"github.com/bazelbuild/rules_typescript/ts_auto_deps/platform"
)

// isAllTestLibrary identifies testonly ts_libraries named "all_tests".  Taze
// will register tests with these rules instead of
// ts_config/ts_development_sources rules to allow users to set up their builds
// differently.
func isAllTestLibrary(bld *build.File, r *build.Rule) bool {
	if !ruleMatches(bld, r, "ts_library", ruleTypeTest) {
		return false
	}

	if r.Name() != "all_tests" {
		return false
	}

	return true
}

func getAllTestLibraries(bld *build.File) []*build.Rule {
	var allTestRules []*build.Rule
	for _, r := range buildRules(bld, "ts_library") {
		if isAllTestLibrary(bld, r) {
			allTestRules = append(allTestRules, r)
		}
	}
	return allTestRules
}

// RegisterTestRules registers ts_library test targets with the project's
// ts_config and ts_development_sources rules.  It may also register the tests
// with a testonly ts_library named "all_tests", which allows users to set up
// their own BUILD layout.  It's separated from UpdateBUILD since it's
// non-local, multiple packages may all need to make writes to the same
// ts_config.  It returns a set of the paths for the packages that were updated.
func (upd *Updater) RegisterTestRules(ctx context.Context, paths ...string) (bool, map[string]bool, error) {
	reg := &buildRegistry{make(map[string]*build.File), make(map[*build.File]bool)}
	var g3root string
	updatedAncestorPackages := make(map[string]bool)
	for _, path := range paths {
		// declare variables manually so that g3root doesn't get overwritten by a :=
		// declaration
		var err error
		var buildPath string
		g3root, buildPath, _, err = getBUILDPath(ctx, path)
		if err != nil {
			return false, nil, err
		}
		bld, err := reg.readBUILD(ctx, g3root, buildPath)
		if err != nil {
			return false, nil, err
		}
		for _, tr := range getRules(bld, "ts_library", ruleTypeTest) {
			// don't register all_test libraries themselves
			if isAllTestLibrary(bld, tr) {
				continue
			}
			platform.Infof("Registering test rule in closest ts_config & ts_development_sources")
			target := AbsoluteBazelTarget(bld, tr.Name())
			ancestorBuild, err := reg.registerTestRule(ctx, bld, tsConfig, g3root, target)
			if err != nil {
				return false, nil, err
			}
			if ancestorBuild != "" {
				updatedAncestorPackages[ancestorBuild] = true
			}
			// NodeJS rules should not be added to ts_development_sources automatically, because
			// they typically do not run in the browser.
			if tr.AttrString("runtime") != "nodejs" {
				ancestorBuild, err := reg.registerTestRule(ctx, bld, tsDevSrcs, g3root, target)
				if err != nil {
					return false, nil, err
				}
				if ancestorBuild != "" {
					updatedAncestorPackages[ancestorBuild] = true
				}
			}
		}
	}

	updated := false
	for b := range reg.filesToUpdate {
		fmt.Printf("Registered test(s) in %s\n", b.Path)
		fileChanged, err := upd.maybeWriteBUILD(ctx, filepath.Join(g3root, b.Path), b)
		if err != nil {
			return false, nil, err
		}
		updated = updated || fileChanged
	}

	return updated, updatedAncestorPackages, nil
}

// buildRegistry buffers reads and writes done while registering ts_libraries
// with ts_config and ts_development_sources rules, so that registers from
// multiple packages all get applied at once.
type buildRegistry struct {
	bldFiles      map[string]*build.File
	filesToUpdate map[*build.File]bool
}

func (reg *buildRegistry) readBUILD(ctx context.Context, workspaceRoot, buildFilePath string) (*build.File, error) {
	normalizedG3Path, err := getWorkspaceRelativePath(workspaceRoot, buildFilePath)
	if err != nil {
		return nil, err
	}

	if bld, ok := reg.bldFiles[normalizedG3Path]; ok {
		return bld, nil
	}

	bld, err := readBUILD(ctx, buildFilePath, normalizedG3Path)
	if err != nil {
		return nil, err
	}
	if bld == nil {
		// The BUILD file didn't exist, so create a new, empty one.
		bld = &build.File{Path: normalizedG3Path, Type: build.TypeBuild}
	}

	reg.bldFiles[normalizedG3Path] = bld

	return bld, nil
}

func (reg *buildRegistry) registerForPossibleUpdate(bld *build.File) {
	reg.filesToUpdate[bld] = true
}

type registerTarget int

const (
	tsConfig registerTarget = iota
	tsDevSrcs
)

func (rt registerTarget) kind() string {
	if rt == tsConfig {
		return "ts_config"
	}

	return "ts_development_sources"
}

func (rt registerTarget) ruleType() ruleType {
	if rt == tsConfig {
		return ruleTypeAny
	}

	return ruleTypeTest
}

// registerTestRule searches ancestor packages for a rule matching the register
// target and adds the given target to it. If an all_tests library is found, the
// rule is registered with it, instead of specified register target. Prints a
// warning if no rule is found, but only returns an error if adding the
// dependency fails.
func (reg *buildRegistry) registerTestRule(ctx context.Context, bld *build.File, rt registerTarget, g3root, target string) (string, error) {
	if buildHasDisableTaze(bld) {
		return "", nil
	}

	var ruleToRegister *build.Rule
	for _, r := range bld.Rules("") {
		if isAllTestLibrary(bld, r) {
			if hasDependency(bld, r, target) {
				return "", nil
			}

			// an all_tests library takes presidence over a registerTarget, and there
			// can only be one, since there can only be one rule with a given name, so
			// can just break after finding
			ruleToRegister = r
			break
		}
		if ruleMatches(bld, r, rt.kind(), rt.ruleType()) {
			if hasDependency(bld, r, target) {
				return "", nil
			}

			// keep overwriting ruleToRegister so the last match in the BUILD gets
			// used
			ruleToRegister = r
		}
	}

	if ruleToRegister != nil {
		addDep(bld, ruleToRegister, target)
		reg.registerForPossibleUpdate(bld)
		return filepath.Dir(bld.Path), nil
	}

	parentDir := filepath.Dir(filepath.Dir(bld.Path))
	for parentDir != "." && parentDir != "/" {
		buildFile := filepath.Join(g3root, parentDir, "BUILD")
		if _, err := platform.Stat(ctx, buildFile); err == nil {
			parent, err := reg.readBUILD(ctx, g3root, buildFile)
			if err != nil {
				return "", err
			}
			return reg.registerTestRule(ctx, parent, rt, g3root, target)
		}
		parentDir = filepath.Dir(parentDir)
	}
	fmt.Printf("WARNING: no %s rule in parent packages of %s to register with.\n",
		rt.kind(), target)
	return "", nil
}

var wellKnownBuildRules = []struct {
	name     string
	attrName string
}{
	{
		name:     "karma_polymer_test",
		attrName: "test_ts_deps",
	},
	{
		name:     "wct_closure_test_suite",
		attrName: "js_deps",
	},
	{
		name:     "jasmine_node_test",
		attrName: "deps",
	},
	{
		name:     "karma_web_test_suite",
		attrName: "deps",
	},
	{
		name:     "boq_jswire_test_library",
		attrName: "deps",
	},
}

// isRegisteredWithAlternateTestRule returns true if the rule is already
// registered with a well known test rule, such as karma_polymer_test,
// wct_closure_test_suite or jasmine_node_test.
func isRegisteredWithAlternateTestRule(bld *build.File, r *build.Rule, dep string) bool {
	pkg := filepath.Dir(bld.Path)
	for _, wkbr := range wellKnownBuildRules {
		if isKind(r, wkbr.name) {
			testTsDeps := r.Attr(wkbr.attrName)
			if edit.ListFind(testTsDeps, dep, pkg) != nil {
				return true
			}
		}
	}
	return false
}
