// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package android

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"android/soong/bazel"

	"github.com/google/blueprint"
	"github.com/google/blueprint/pathtools"
)

// bazel_paths contains methods to:
//   * resolve Soong path and module references into bazel.LabelList
//   * resolve Bazel path references into Soong-compatible paths
//
// There is often a similar method for Bazel as there is for Soong path handling and should be used
// in similar circumstances
//
//   Bazel                                Soong
//   ==============================================================
//   BazelLabelForModuleSrc               PathForModuleSrc
//   BazelLabelForModuleSrcExcludes       PathForModuleSrcExcludes
//   BazelLabelForModuleDeps              n/a
//   tbd                                  PathForSource
//   tbd                                  ExistentPathsForSources
//   PathForBazelOut                      PathForModuleOut
//
// Use cases:
//  * Module contains a property (often tagged `android:"path"`) that expects paths *relative to the
//    module directory*:
//     * BazelLabelForModuleSrcExcludes, if the module also contains an excludes_<propname> property
//     * BazelLabelForModuleSrc, otherwise
//  * Converting references to other modules to Bazel Labels:
//     BazelLabelForModuleDeps
//  * Converting a path obtained from bazel_handler cquery results:
//     PathForBazelOut
//
// NOTE: all Soong globs are expanded within Soong rather than being converted to a Bazel glob
//       syntax. This occurs because Soong does not have a concept of crossing package boundaries,
//       so the glob as computed by Soong may contain paths that cross package-boundaries. These
//       would be unknowingly omitted if the glob were handled by Bazel. By expanding globs within
//       Soong, we support identification and detection (within Bazel) use of paths that cross
//       package boundaries.
//
// Path resolution:
// * filepath/globs: resolves as itself or is converted to an absolute Bazel label (e.g.
//   //path/to/dir:<filepath>) if path exists in a separate package or subpackage.
// * references to other modules (using the ":name{.tag}" syntax). These resolve as a Bazel label
//   for a target. If the Bazel target is in the local module directory, it will be returned
//   relative to the current package (e.g.  ":<target>"). Otherwise, it will be returned as an
//   absolute Bazel label (e.g.  "//path/to/dir:<target>"). If the reference to another module
//   cannot be resolved,the function will panic. This is often due to the dependency not being added
//   via an AddDependency* method.

// BazelConversionContext is a minimal context interface to check if a module should be converted by bp2build,
// with functions containing information to match against allowlists and denylists.
// If a module is deemed to be convertible by bp2build, then it should rely on a
// BazelConversionPathContext for more functions for dep/path features.
type BazelConversionContext interface {
	Config() Config

	Module() Module
	OtherModuleType(m blueprint.Module) string
	OtherModuleName(m blueprint.Module) string
	OtherModuleDir(m blueprint.Module) string
	ModuleErrorf(format string, args ...interface{})
}

// A subset of the ModuleContext methods which are sufficient to resolve references to paths/deps in
// order to form a Bazel-compatible label for conversion.
type BazelConversionPathContext interface {
	EarlyModulePathContext
	BazelConversionContext

	ModuleName() string
	ModuleType() string
	ModuleErrorf(fmt string, args ...interface{})
	PropertyErrorf(property, fmt string, args ...interface{})
	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
	ModuleFromName(name string) (blueprint.Module, bool)
	AddUnconvertedBp2buildDep(string)
	AddMissingBp2buildDep(dep string)
}

// BazelLabelForModuleDeps expects a list of reference to other modules, ("<module>"
// or ":<module>") and returns a Bazel-compatible label which corresponds to dependencies on the
// module within the given ctx.
func BazelLabelForModuleDeps(ctx Bp2buildMutatorContext, modules []string) bazel.LabelList {
	return BazelLabelForModuleDepsWithFn(ctx, modules, BazelModuleLabel, /*markAsDeps=*/true)
}

// BazelLabelForModuleWholeDepsExcludes expects two lists: modules (containing modules to include in
// the list), and excludes (modules to exclude from the list). Both of these should contain
// references to other modules, ("<module>" or ":<module>"). It returns a Bazel-compatible label
// list which corresponds to dependencies on the module within the given ctx, and the excluded
// dependencies.  Prebuilt dependencies will be appended with _alwayslink so they can be handled as
// whole static libraries.
func BazelLabelForModuleDepsExcludes(ctx Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
	return BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, BazelModuleLabel)
}

// BazelLabelForModuleDepsWithFn expects a list of reference to other modules, ("<module>"
// or ":<module>") and applies moduleToLabelFn to determine and return a Bazel-compatible label
// which corresponds to dependencies on the module within the given ctx.
func BazelLabelForModuleDepsWithFn(ctx Bp2buildMutatorContext, modules []string,
	moduleToLabelFn func(BazelConversionPathContext, blueprint.Module) string,
	markAsDeps bool) bazel.LabelList {
	var labels bazel.LabelList
	// In some cases, a nil string list is different than an explicitly empty list.
	if len(modules) == 0 && modules != nil {
		labels.Includes = []bazel.Label{}
		return labels
	}
	modules = FirstUniqueStrings(modules)
	for _, module := range modules {
		bpText := module
		if m := SrcIsModule(module); m == "" {
			module = ":" + module
		}
		if m, t := SrcIsModuleWithTag(module); m != "" {
			l := getOtherModuleLabel(ctx, m, t, moduleToLabelFn, markAsDeps)
			if l != nil {
				l.OriginalModuleName = bpText
				labels.Includes = append(labels.Includes, *l)
			}
		} else {
			ctx.ModuleErrorf("%q, is not a module reference", module)
		}
	}
	return labels
}

// BazelLabelForModuleDepsExcludesWithFn expects two lists: modules (containing modules to include in the
// list), and excludes (modules to exclude from the list). Both of these should contain references
// to other modules, ("<module>" or ":<module>"). It applies moduleToLabelFn to determine and return a
// Bazel-compatible label list which corresponds to dependencies on the module within the given ctx, and
// the excluded dependencies.
func BazelLabelForModuleDepsExcludesWithFn(ctx Bp2buildMutatorContext, modules, excludes []string,
	moduleToLabelFn func(BazelConversionPathContext, blueprint.Module) string) bazel.LabelList {
	moduleLabels := BazelLabelForModuleDepsWithFn(ctx, RemoveListFromList(modules, excludes), moduleToLabelFn, /*markAsDeps=*/true)
	if len(excludes) == 0 {
		return moduleLabels
	}
	excludeLabels := BazelLabelForModuleDepsWithFn(ctx, excludes, moduleToLabelFn, /*markAsDeps=*/false)
	return bazel.LabelList{
		Includes: moduleLabels.Includes,
		Excludes: excludeLabels.Includes,
	}
}

func BazelLabelForModuleSrcSingle(ctx Bp2buildMutatorContext, path string) bazel.Label {
	if srcs := BazelLabelForModuleSrcExcludes(ctx, []string{path}, []string(nil)).Includes; len(srcs) > 0 {
		return srcs[0]
	}
	return bazel.Label{}
}

func BazelLabelForModuleDepSingle(ctx Bp2buildMutatorContext, path string) bazel.Label {
	if srcs := BazelLabelForModuleDepsExcludes(ctx, []string{path}, []string(nil)).Includes; len(srcs) > 0 {
		return srcs[0]
	}
	return bazel.Label{}
}

// BazelLabelForModuleSrc expects a list of path (relative to local module directory) and module
// references (":<module>") and returns a bazel.LabelList{} containing the resolved references in
// paths, relative to the local module, or Bazel-labels (absolute if in a different package or
// relative if within the same package).
// Properties must have been annotated with struct tag `android:"path"` so that dependencies modules
// will have already been handled by the pathdeps mutator.
func BazelLabelForModuleSrc(ctx Bp2buildMutatorContext, paths []string) bazel.LabelList {
	return BazelLabelForModuleSrcExcludes(ctx, paths, []string(nil))
}

// BazelLabelForModuleSrc expects lists of path and excludes (relative to local module directory)
// and module references (":<module>") and returns a bazel.LabelList{} containing the resolved
// references in paths, minus those in excludes, relative to the local module, or Bazel-labels
// (absolute if in a different package or relative if within the same package).
// Properties must have been annotated with struct tag `android:"path"` so that dependencies modules
// will have already been handled by the pathdeps mutator.
func BazelLabelForModuleSrcExcludes(ctx Bp2buildMutatorContext, paths, excludes []string) bazel.LabelList {
	excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil), false)
	excluded := make([]string, 0, len(excludeLabels.Includes))
	for _, e := range excludeLabels.Includes {
		excluded = append(excluded, e.Label)
	}
	labels := expandSrcsForBazel(ctx, paths, excluded, true)
	labels.Excludes = excludeLabels.Includes
	labels = TransformSubpackagePaths(ctx.Config(), ctx.ModuleDir(), labels)
	return labels
}

func BazelLabelForSrcPatternExcludes(ctx BazelConversionPathContext, dir, pattern string, excludes []string) bazel.LabelList {
	topRelPaths, err := ctx.GlobWithDeps(filepath.Join(dir, pattern), excludes)
	if err != nil {
		ctx.ModuleErrorf("Could not search dir: %s for pattern %s due to %v\n", dir, pattern, err)
	}
	// An intermediate list of labels relative to `dir` that assumes that there no subpacakges beneath `dir`
	dirRelLabels := []bazel.Label{}
	for _, topRelPath := range topRelPaths {
		dirRelPath := Rel(ctx, dir, topRelPath)
		dirRelLabels = append(dirRelLabels, bazel.Label{Label: "./" + dirRelPath})
	}
	// Return the package boudary resolved labels
	return TransformSubpackagePaths(ctx.Config(), dir, bazel.MakeLabelList(dirRelLabels))
}

// Returns true if a prefix + components[:i] is a package boundary.
//
// A package boundary is determined by a BUILD file in the directory. This can happen in 2 cases:
//
//  1. An Android.bp exists, which bp2build will always convert to a sibling BUILD file.
//  2. An Android.bp doesn't exist, but a checked-in BUILD/BUILD.bazel file exists, and that file
//     is allowlisted by the bp2build configuration to be merged into the symlink forest workspace.
func isPackageBoundary(config Config, prefix string, components []string, componentIndex int) bool {
	isSymlink := func(c Config, path string) bool {
		f, err := c.fs.Lstat(path)
		if err != nil {
			// The file does not exist
			return false
		}
		return f.Mode()&os.ModeSymlink == os.ModeSymlink
	}
	prefix = filepath.Join(prefix, filepath.Join(components[:componentIndex+1]...))
	if exists, _, _ := config.fs.Exists(filepath.Join(prefix, "Android.bp")); exists {
		return true
	} else if config.Bp2buildPackageConfig.ShouldKeepExistingBuildFileForDir(prefix) || isSymlink(config, prefix) {
		if exists, _, _ := config.fs.Exists(filepath.Join(prefix, "BUILD")); exists {
			return true
		} else if exists, _, _ := config.fs.Exists(filepath.Join(prefix, "BUILD.bazel")); exists {
			return true
		}
	}

	return false
}

// Transform a path (if necessary) to acknowledge package boundaries
//
// e.g. something like
//
//	async_safe/include/async_safe/CHECK.h
//
// might become
//
//	//bionic/libc/async_safe:include/async_safe/CHECK.h
//
// if the "async_safe" directory is actually a package and not just a directory.
//
// In particular, paths that extend into packages are transformed into absolute labels beginning with //.
func transformSubpackagePath(cfg Config, dir string, path bazel.Label) bazel.Label {
	var newPath bazel.Label

	// Don't transform OriginalModuleName
	newPath.OriginalModuleName = path.OriginalModuleName
	// if it wasn't a module, store the original path. We may need the original path to replace
	// references if it is actually in another package
	if path.OriginalModuleName == "" {
		newPath.OriginalModuleName = path.Label
	}

	if strings.HasPrefix(path.Label, "//") {
		// Assume absolute labels are already correct (e.g. //path/to/some/package:foo.h)
		newPath.Label = path.Label
		return newPath
	}
	if strings.HasPrefix(path.Label, "./") {
		// Drop "./" for consistent handling of paths.
		// Specifically, to not let "." be considered a package boundary.
		// Say `inputPath` is `x/Android.bp` and that file has some module
		// with `srcs=["y/a.c", "z/b.c"]`.
		// And say the directory tree is:
		//     x
		//     ├── Android.bp
		//     ├── y
		//     │   ├── a.c
		//     │   └── Android.bp
		//     └── z
		//         └── b.c
		// Then bazel equivalent labels in srcs should be:
		//   //x/y:a.c, x/z/b.c
		// The above should still be the case if `x/Android.bp` had
		//   srcs=["./y/a.c", "./z/b.c"]
		// However, if we didn't strip "./", we'd get
		//   //x/./y:a.c, //x/.:z/b.c
		path.Label = strings.TrimPrefix(path.Label, "./")
	}
	pathComponents := strings.Split(path.Label, "/")
	newLabel := ""
	foundPackageBoundary := false
	// Check the deepest subdirectory first and work upwards
	for i := len(pathComponents) - 1; i >= 0; i-- {
		pathComponent := pathComponents[i]
		var sep string
		if !foundPackageBoundary && isPackageBoundary(cfg, dir, pathComponents, i) {
			sep = ":"
			foundPackageBoundary = true
		} else {
			sep = "/"
		}
		if newLabel == "" {
			newLabel = pathComponent
		} else {
			newLabel = pathComponent + sep + newLabel
		}
	}
	if foundPackageBoundary {
		// Ensure paths end up looking like //bionic/... instead of //./bionic/...
		moduleDir := dir
		if strings.HasPrefix(moduleDir, ".") {
			moduleDir = moduleDir[1:]
		}
		// Make the path into an absolute label (e.g. //bionic/libc/foo:bar.h instead of just foo:bar.h)
		if moduleDir == "" {
			newLabel = "//" + newLabel
		} else {
			newLabel = "//" + moduleDir + "/" + newLabel
		}
	}
	newPath.Label = newLabel

	return newPath
}

// Transform paths to acknowledge package boundaries
// See transformSubpackagePath() for more information
func TransformSubpackagePaths(cfg Config, dir string, paths bazel.LabelList) bazel.LabelList {
	var newPaths bazel.LabelList
	for _, include := range paths.Includes {
		newPaths.Includes = append(newPaths.Includes, transformSubpackagePath(cfg, dir, include))
	}
	for _, exclude := range paths.Excludes {
		newPaths.Excludes = append(newPaths.Excludes, transformSubpackagePath(cfg, dir, exclude))
	}
	return newPaths
}

// Converts root-relative Paths to a list of bazel.Label relative to the module in ctx.
func RootToModuleRelativePaths(ctx BazelConversionPathContext, paths Paths) []bazel.Label {
	var newPaths []bazel.Label
	for _, path := range PathsWithModuleSrcSubDir(ctx, paths, "") {
		s := path.Rel()
		newPaths = append(newPaths, bazel.Label{Label: s})
	}
	return newPaths
}

var Bp2buildDepTag bp2buildDepTag

type bp2buildDepTag struct {
	blueprint.BaseDependencyTag
}

// expandSrcsForBazel returns bazel.LabelList with paths rooted from the module's local source
// directory and Bazel target labels, excluding those included in the excludes argument (which
// should already be expanded to resolve references to Soong-modules). Valid elements of paths
// include:
//   - filepath, relative to local module directory, resolves as a filepath relative to the local
//     source directory
//   - glob, relative to the local module directory, resolves as filepath(s), relative to the local
//     module directory. Because Soong does not have a concept of crossing package boundaries, the
//     glob as computed by Soong may contain paths that cross package-boundaries that would be
//     unknowingly omitted if the glob were handled by Bazel. To allow identification and detect
//     (within Bazel) use of paths that cross package boundaries, we expand globs within Soong rather
//     than converting Soong glob syntax to Bazel glob syntax. **Invalid for excludes.**
//   - other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer
//     or OutputFileProducer. These resolve as a Bazel label for a target. If the Bazel target is in
//     the local module directory, it will be returned relative to the current package (e.g.
//     ":<target>"). Otherwise, it will be returned as an absolute Bazel label (e.g.
//     "//path/to/dir:<target>"). If the reference to another module cannot be resolved,the function
//     will panic.
//
// Properties passed as the paths or excludes argument must have been annotated with struct tag
// `android:"path"` so that dependencies on other modules will have already been handled by the
// pathdeps mutator.
func expandSrcsForBazel(ctx Bp2buildMutatorContext, paths, expandedExcludes []string, markAsDeps bool) bazel.LabelList {
	if paths == nil {
		return bazel.LabelList{}
	}
	labels := bazel.LabelList{
		Includes: []bazel.Label{},
	}

	// expandedExcludes contain module-dir relative paths, but root-relative paths
	// are needed for GlobFiles later.
	var rootRelativeExpandedExcludes []string
	for _, e := range expandedExcludes {
		rootRelativeExpandedExcludes = append(rootRelativeExpandedExcludes, filepath.Join(ctx.ModuleDir(), e))
	}

	for _, p := range paths {
		if m, tag := SrcIsModuleWithTag(p); m != "" {
			l := getOtherModuleLabel(ctx, m, tag, BazelModuleLabel, markAsDeps)
			if l != nil && !InList(l.Label, expandedExcludes) {
				if strings.HasPrefix(m, "//") {
					// this is a module in a soong namespace
					// It appears as //<namespace>:<module_name> in srcs, and not ://<namespace>:<module_name>
					l.OriginalModuleName = m
				} else {
					l.OriginalModuleName = fmt.Sprintf(":%s", m)
				}
				labels.Includes = append(labels.Includes, *l)
			}
		} else {
			var expandedPaths []bazel.Label
			if pathtools.IsGlob(p) {
				// e.g. turn "math/*.c" in
				// external/arm-optimized-routines to external/arm-optimized-routines/math/*.c
				rootRelativeGlobPath := pathForModuleSrc(ctx, p).String()
				expandedPaths = RootToModuleRelativePaths(ctx, GlobFiles(ctx, rootRelativeGlobPath, rootRelativeExpandedExcludes))
			} else {
				if !InList(p, expandedExcludes) {
					expandedPaths = append(expandedPaths, bazel.Label{Label: p})
				}
			}
			labels.Includes = append(labels.Includes, expandedPaths...)
		}
	}
	return labels
}

// getOtherModuleLabel returns a bazel.Label for the given dependency/tag combination for the
// module. The label will be relative to the current directory if appropriate. The dependency must
// already be resolved by either deps mutator or path deps mutator.
func getOtherModuleLabel(ctx Bp2buildMutatorContext, dep, tag string,
	labelFromModule func(BazelConversionPathContext, blueprint.Module) string,
	markAsDep bool) *bazel.Label {
	m, _ := ctx.ModuleFromName(dep)
	// The module was not found in an Android.bp file, this is often due to:
	//		* a limited manifest
	//		* a required module not being converted from Android.mk
	if m == nil {
		ctx.AddMissingBp2buildDep(dep)
		return &bazel.Label{
			Label: ":" + dep + "__BP2BUILD__MISSING__DEP",
		}
	}
	// Returns true if a dependency from the current module to the target module
	// should be skipped; doing so is a hack to circumvent certain problematic
	// scenarios that will be addressed in the future.
	shouldSkipDep := func(dep string) bool {
		// Don't count dependencies of "libc". This is a hack to circumvent the
		// fact that, in a variantless build graph, "libc" has a dependency on itself.
		if ctx.ModuleName() == "libc" {
			return true
		}

		// TODO: b/303307672: Dependencies on this module happen to "work" because
		// there is a source file with the same name as this module in the
		// same directory. We should remove this hack and enforce the underlying
		// module of this name is the actual one used.
		if dep == "mke2fs.conf" {
			return true
		}

		// TODO: b/303310285: Remove this special-casing once all dependencies of
		// crtbegin_dynamic are convertible
		if ctx.ModuleName() == "crtbegin_dynamic" {
			return true
		}

		return false
	}
	if markAsDep && !shouldSkipDep(dep) {
		ctx.AddDependency(ctx.Module(), Bp2buildDepTag, dep)
	}
	if !convertedToBazel(ctx, m) {
		ctx.AddUnconvertedBp2buildDep(dep)
	}
	label := BazelModuleLabel(ctx, ctx.Module())
	otherLabel := labelFromModule(ctx, m)

	// TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets.
	if (tag != "" && m.Name() == "framework-res") ||
		(tag == ".generated_srcjars" && ctx.OtherModuleType(m) == "java_aconfig_library") {
		otherLabel += tag
	}

	if samePackage(label, otherLabel) {
		otherLabel = bazelShortLabel(otherLabel)
	}

	return &bazel.Label{
		Label: otherLabel,
	}
}

func BazelModuleLabel(ctx BazelConversionPathContext, module blueprint.Module) string {
	// TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets.
	if !convertedToBazel(ctx, module) || isGoModule(module) {
		return bp2buildModuleLabel(ctx, module)
	}
	b, _ := module.(Bazelable)
	return b.GetBazelLabel(ctx, module)
}

func bazelShortLabel(label string) string {
	i := strings.Index(label, ":")
	if i == -1 {
		panic(fmt.Errorf("Could not find the ':' character in '%s', expected a fully qualified label.", label))
	}
	return label[i:]
}

func bazelPackage(label string) string {
	i := strings.Index(label, ":")
	if i == -1 {
		panic(fmt.Errorf("Could not find the ':' character in '%s', expected a fully qualified label.", label))
	}
	return label[0:i]
}

func samePackage(label1, label2 string) bool {
	return bazelPackage(label1) == bazelPackage(label2)
}

func bp2buildModuleLabel(ctx BazelConversionContext, module blueprint.Module) string {
	moduleName := moduleNameWithPossibleOverride(ctx, module, ctx.OtherModuleName(module))
	moduleDir := moduleDirWithPossibleOverride(ctx, module, ctx.OtherModuleDir(module))
	if moduleDir == Bp2BuildTopLevel {
		moduleDir = ""
	}
	if a, ok := module.(Module); ok && IsModulePrebuilt(a) {
		moduleName = RemoveOptionalPrebuiltPrefix(moduleName)
	}
	return fmt.Sprintf("//%s:%s", moduleDir, moduleName)
}

// BazelOutPath is a Bazel output path compatible to be used for mixed builds within Soong/Ninja.
type BazelOutPath struct {
	OutputPath
}

// ensure BazelOutPath implements Path
var _ Path = BazelOutPath{}

// ensure BazelOutPath implements genPathProvider
var _ genPathProvider = BazelOutPath{}

// ensure BazelOutPath implements objPathProvider
var _ objPathProvider = BazelOutPath{}

func (p BazelOutPath) genPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleGenPath {
	return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}

func (p BazelOutPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath {
	return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}

// PathForBazelOutRelative returns a BazelOutPath representing the path under an output directory dedicated to
// bazel-owned outputs. Calling .Rel() on the result will give the input path as relative to the given
// relativeRoot.
func PathForBazelOutRelative(ctx PathContext, relativeRoot string, path string) BazelOutPath {
	validatedPath, err := validatePath(filepath.Join("execroot", "__main__", path))
	if err != nil {
		reportPathError(ctx, err)
	}
	var relativeRootPath string
	if pathComponents := strings.SplitN(path, "/", 4); len(pathComponents) >= 3 &&
		pathComponents[0] == "bazel-out" && pathComponents[2] == "bin" {
		// If the path starts with something like: bazel-out/linux_x86_64-fastbuild-ST-b4ef1c4402f9/bin/
		// make it relative to that folder. bazel-out/volatile-status.txt is an example
		// of something that starts with bazel-out but is not relative to the bin folder
		relativeRootPath = filepath.Join("execroot", "__main__", pathComponents[0], pathComponents[1], pathComponents[2], relativeRoot)
	} else {
		relativeRootPath = filepath.Join("execroot", "__main__", relativeRoot)
	}

	var relPath string
	if relPath, err = filepath.Rel(relativeRootPath, validatedPath); err != nil || strings.HasPrefix(relPath, "../") {
		// We failed to make this path relative to execroot/__main__, fall back to a non-relative path
		// One case where this happens is when path is ../bazel_tools/something
		relativeRootPath = ""
		relPath = validatedPath
	}

	outputPath := OutputPath{
		basePath{"", ""},
		ctx.Config().soongOutDir,
		ctx.Config().BazelContext.OutputBase(),
	}

	return BazelOutPath{
		// .withRel() appends its argument onto the current path, and only the most
		// recently appended part is returned by outputPath.rel().
		// So outputPath.rel() will return relPath.
		OutputPath: outputPath.withRel(relativeRootPath).withRel(relPath),
	}
}

// PathForBazelOut returns a BazelOutPath representing the path under an output directory dedicated to
// bazel-owned outputs.
func PathForBazelOut(ctx PathContext, path string) BazelOutPath {
	return PathForBazelOutRelative(ctx, "", path)
}

// PathsForBazelOut returns a list of paths representing the paths under an output directory
// dedicated to Bazel-owned outputs.
func PathsForBazelOut(ctx PathContext, paths []string) Paths {
	outs := make(Paths, 0, len(paths))
	for _, p := range paths {
		outs = append(outs, PathForBazelOut(ctx, p))
	}
	return outs
}

// BazelStringOrLabelFromProp splits a Soong module property that can be
// either a string literal, path (with android:path tag) or a module reference
// into separate bazel string or label attributes. Bazel treats string and label
// attributes as distinct types, so this function categorizes a string property
// into either one of them.
//
// e.g. apex.private_key = "foo.pem" can either refer to:
//
// 1. "foo.pem" in the current directory -> file target
// 2. "foo.pem" module -> rule target
// 3. "foo.pem" file in a different directory, prefixed by a product variable handled
// in a bazel macro. -> string literal
//
// For the first two cases, they are defined using the label attribute. For the third case,
// it's defined with the string attribute.
func BazelStringOrLabelFromProp(
	ctx Bp2buildMutatorContext,
	propToDistinguish *string) (bazel.LabelAttribute, bazel.StringAttribute) {

	var labelAttr bazel.LabelAttribute
	var strAttr bazel.StringAttribute

	if propToDistinguish == nil {
		// nil pointer
		return labelAttr, strAttr
	}

	prop := String(propToDistinguish)
	if SrcIsModule(prop) != "" {
		// If it's a module (SrcIsModule will return the module name), set the
		// resolved label to the label attribute.
		labelAttr.SetValue(BazelLabelForModuleDepSingle(ctx, prop))
	} else {
		// Not a module name. This could be a string literal or a file target in
		// the current dir. Check if the path exists:
		path := ExistentPathForSource(ctx, ctx.ModuleDir(), prop)

		if path.Valid() && parentDir(path.String()) == ctx.ModuleDir() {
			// If it exists and the path is relative to the current dir, resolve the bazel label
			// for the _file target_ and set it to the label attribute.
			//
			// Resolution is necessary because this could be a file in a subpackage.
			labelAttr.SetValue(BazelLabelForModuleSrcSingle(ctx, prop))
		} else {
			// Otherwise, treat it as a string literal and assign to the string attribute.
			strAttr.Value = propToDistinguish
		}
	}

	return labelAttr, strAttr
}
