package updater

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

	"github.com/bazelbuild/buildtools/build"
	"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.
func (upd *Updater) RegisterTestRules(ctx context.Context, paths ...string) (bool, error) {
	reg := &buildRegistry{make(map[string]*build.File), make(map[*build.File]bool)}
	var g3root string
	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, err
		}
		bld, err := reg.readBUILD(ctx, g3root, buildPath)
		if err != nil {
			return false, err
		}
		if tr := getRule(bld, "ts_library", ruleTypeTest); tr != nil {
			// 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())
			if err := reg.registerTestRule(ctx, bld, tsConfig, g3root, target); err != nil {
				return false, err
			}
			// 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" {
				if err := reg.registerTestRule(ctx, bld, tsDevSrcs, g3root, target); err != nil {
					return false, err
				}
			}
		}
	}

	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, err
		}
		updated = updated || fileChanged
	}

	return updated, 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 := getAbsoluteBUILDPath(workspaceRoot, buildFilePath)
	if err != nil {
		return nil, err
	}

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

	bld, err := readBUILD(ctx, workspaceRoot, buildFilePath)
	if err != nil {
		return nil, err
	}

	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) 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 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
}
