package python

import (
	"path/filepath"

	"github.com/bazelbuild/bazel-gazelle/config"
	"github.com/bazelbuild/bazel-gazelle/rule"
	"github.com/emirpasic/gods/sets/treeset"
	godsutils "github.com/emirpasic/gods/utils"
)

// targetBuilder builds targets to be generated by Gazelle.
type targetBuilder struct {
	kind              string
	name              string
	pythonProjectRoot string
	bzlPackage        string
	uuid              string
	srcs              *treeset.Set
	deps              *treeset.Set
	resolvedDeps      *treeset.Set
	visibility        *treeset.Set
	main              *string
	imports           []string
}

// newTargetBuilder constructs a new targetBuilder.
func newTargetBuilder(kind, name, pythonProjectRoot, bzlPackage string) *targetBuilder {
	return &targetBuilder{
		kind:              kind,
		name:              name,
		pythonProjectRoot: pythonProjectRoot,
		bzlPackage:        bzlPackage,
		srcs:              treeset.NewWith(godsutils.StringComparator),
		deps:              treeset.NewWith(moduleComparator),
		resolvedDeps:      treeset.NewWith(godsutils.StringComparator),
		visibility:        treeset.NewWith(godsutils.StringComparator),
	}
}

// setUUID sets the given UUID for the target. It's used to index the generated
// target based on this value in addition to the other ways the targets can be
// imported. py_{binary,test} targets in the same Bazel package can add a
// virtual dependency to this UUID that gets resolved in the Resolver interface.
func (t *targetBuilder) setUUID(uuid string) *targetBuilder {
	t.uuid = uuid
	return t
}

// addSrc adds a single src to the target.
func (t *targetBuilder) addSrc(src string) *targetBuilder {
	t.srcs.Add(src)
	return t
}

// addSrcs copies all values from the provided srcs to the target.
func (t *targetBuilder) addSrcs(srcs *treeset.Set) *targetBuilder {
	it := srcs.Iterator()
	for it.Next() {
		t.srcs.Add(it.Value().(string))
	}
	return t
}

// addModuleDependency adds a single module dep to the target.
func (t *targetBuilder) addModuleDependency(dep module) *targetBuilder {
	t.deps.Add(dep)
	return t
}

// addModuleDependencies copies all values from the provided deps to the target.
func (t *targetBuilder) addModuleDependencies(deps *treeset.Set) *targetBuilder {
	it := deps.Iterator()
	for it.Next() {
		t.deps.Add(it.Value().(module))
	}
	return t
}

// addResolvedDependency adds a single dependency the target that has already
// been resolved or generated. The Resolver step doesn't process it further.
func (t *targetBuilder) addResolvedDependency(dep string) *targetBuilder {
	t.resolvedDeps.Add(dep)
	return t
}

// addVisibility adds a visibility to the target.
func (t *targetBuilder) addVisibility(visibility string) *targetBuilder {
	t.visibility.Add(visibility)
	return t
}

// setMain sets the main file to the target.
func (t *targetBuilder) setMain(main string) *targetBuilder {
	t.main = &main
	return t
}

// generateImportsAttribute generates the imports attribute.
// These are a list of import directories to be added to the PYTHONPATH. In our
// case, the value we add is on Bazel sub-packages to be able to perform imports
// relative to the root project package.
func (t *targetBuilder) generateImportsAttribute() *targetBuilder {
	p, _ := filepath.Rel(t.bzlPackage, t.pythonProjectRoot)
	p = filepath.Clean(p)
	if p == "." {
		return t
	}
	t.imports = []string{p}
	return t
}

// build returns the assembled *rule.Rule for the target.
func (t *targetBuilder) build() *rule.Rule {
	r := rule.NewRule(t.kind, t.name)
	if t.uuid != "" {
		r.SetPrivateAttr(uuidKey, t.uuid)
	}
	if !t.srcs.Empty() {
		r.SetAttr("srcs", t.srcs.Values())
	}
	if !t.visibility.Empty() {
		r.SetAttr("visibility", t.visibility.Values())
	}
	if t.main != nil {
		r.SetAttr("main", *t.main)
	}
	if t.imports != nil {
		r.SetAttr("imports", t.imports)
	}
	if !t.deps.Empty() {
		r.SetPrivateAttr(config.GazelleImportsKey, t.deps)
	}
	r.SetPrivateAttr(resolvedDepsKey, t.resolvedDeps)
	return r
}
