/* Copyright 2020 The Bazel Authors. 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 bzl generates a `bzl_library` target for every `.bzl` file in
// each package.
//
// The `bzl_library` rule is provided by
// https://github.com/bazelbuild/bazel-skylib.
//
// This extension is experimental and subject to change. It is not included
// in the default Gazelle binary.
package bzl

import (
	"flag"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strings"

	"github.com/bazelbuild/bazel-gazelle/config"
	"github.com/bazelbuild/bazel-gazelle/label"
	"github.com/bazelbuild/bazel-gazelle/language"
	"github.com/bazelbuild/bazel-gazelle/pathtools"
	"github.com/bazelbuild/bazel-gazelle/repo"
	"github.com/bazelbuild/bazel-gazelle/resolve"
	"github.com/bazelbuild/bazel-gazelle/rule"
	"github.com/bazelbuild/buildtools/build"
)

const languageName = "starlark"
const fileType = ".bzl"

var ignoreSuffix = suffixes{
	"_tests.bzl",
	"_test.bzl",
}

type suffixes []string

func (s suffixes) Matches(test string) bool {
	for _, v := range s {
		if strings.HasSuffix(test, v) {
			return true
		}
	}
	return false
}

type bzlLibraryLang struct{}

// NewLanguage is called by Gazelle to install this language extension in a binary.
func NewLanguage() language.Language {
	return &bzlLibraryLang{}
}

// Name returns the name of the language. This should be a prefix of the
// kinds of rules generated by the language, e.g., "go" for the Go extension
// since it generates "go_library" rules.
func (*bzlLibraryLang) Name() string { return languageName }

// The following methods are implemented to satisfy the
// https://pkg.go.dev/github.com/bazelbuild/bazel-gazelle/resolve?tab=doc#Resolver
// interface, but are otherwise unused.
func (*bzlLibraryLang) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) {}
func (*bzlLibraryLang) CheckFlags(fs *flag.FlagSet, c *config.Config) error          { return nil }
func (*bzlLibraryLang) KnownDirectives() []string                                    { return nil }
func (*bzlLibraryLang) Configure(c *config.Config, rel string, f *rule.File)         {}

// Kinds returns a map of maps rule names (kinds) and information on how to
// match and merge attributes that may be found in rules of those kinds. All
// kinds of rules generated for this language may be found here.
func (*bzlLibraryLang) Kinds() map[string]rule.KindInfo {
	return kinds
}

// Loads returns .bzl files and symbols they define. Every rule generated by
// GenerateRules, now or in the past, should be loadable from one of these
// files.
func (*bzlLibraryLang) Loads() []rule.LoadInfo {
	return []rule.LoadInfo{{
		Name:    "@bazel_skylib//:bzl_library.bzl",
		Symbols: []string{"bzl_library"},
	}}
}

// Fix repairs deprecated usage of language-specific rules in f. This is
// called before the file is indexed. Unless c.ShouldFix is true, fixes
// that delete or rename rules should not be performed.
func (*bzlLibraryLang) Fix(c *config.Config, f *rule.File) {}

// Imports returns a list of ImportSpecs that can be used to import the rule
// r. This is used to populate RuleIndex.
//
// If nil is returned, the rule will not be indexed. If any non-nil slice is
// returned, including an empty slice, the rule will be indexed.
func (b *bzlLibraryLang) Imports(c *config.Config, r *rule.Rule, f *rule.File) []resolve.ImportSpec {
	srcs := r.AttrStrings("srcs")
	imports := make([]resolve.ImportSpec, 0, len(srcs))

	for _, src := range srcs {
		spec := resolve.ImportSpec{
			// Lang is the language in which the import string appears (this should
			// match Resolver.Name).
			Lang: languageName,
			// Imp is an import string for the library.
			Imp: fmt.Sprintf("//%s:%s", f.Pkg, src),
		}

		imports = append(imports, spec)
	}

	return imports
}

// Embeds returns a list of labels of rules that the given rule embeds. If
// a rule is embedded by another importable rule of the same language, only
// the embedding rule will be indexed. The embedding rule will inherit
// the imports of the embedded rule.
// Since SkyLark doesn't support embedding this should always return nil.
func (*bzlLibraryLang) Embeds(r *rule.Rule, from label.Label) []label.Label { return nil }

// Resolve translates imported libraries for a given rule into Bazel
// dependencies. Information about imported libraries is returned for each
// rule generated by language.GenerateRules in
// language.GenerateResult.Imports. Resolve generates a "deps" attribute (or
// the appropriate language-specific equivalent) for each import according to
// language-specific rules and heuristics.
func (*bzlLibraryLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, importsRaw interface{}, from label.Label) {
	imports := importsRaw.([]string)

	r.DelAttr("deps")

	if len(imports) == 0 {
		return
	}

	deps := make([]string, 0, len(imports))
	for _, imp := range imports {
		impLabel, err := label.Parse(imp)
		if err != nil {
			log.Printf("%s: import of %q is invalid: %v", from.String(), imp, err)
			continue
		}

		// the index only contains absolute labels, not relative
		impLabel = impLabel.Abs(from.Repo, from.Pkg)

		if impLabel.Repo == "bazel_tools" {
			// The @bazel_tools repo is tricky because it is a part of the "shipped
			// with bazel" core library for interacting with the outside world.
			// This means that it can not depend on skylib. Fortunately there is a
			// fairly simple workaround for this, which is that you can add those
			// bzl files as `deps` entries.
			deps = append(deps, imp)
			continue
		}

		if impLabel.Repo != "" || !c.IndexLibraries {
			// This is a dependency that is external to the current repo, or indexing
			// is disabled so take a guess at what the target name should be.
			deps = append(deps, strings.TrimSuffix(imp, fileType))
			continue
		}

		res := resolve.ImportSpec{
			Lang: languageName,
			Imp:  impLabel.String(),
		}
		matches := ix.FindRulesByImportWithConfig(c, res, languageName)
		if len(matches) == 0 {
			log.Printf("%s: %q (%s) was not found in dependency index. Skipping. This may result in an incomplete deps section and require manual BUILD file intervention.\n", from.String(), imp, impLabel.String())
		}

		for _, m := range matches {
			depLabel := m.Label
			depLabel = depLabel.Rel(from.Repo, from.Pkg)
			deps = append(deps, depLabel.String())
		}
	}

	sort.Strings(deps)
	if len(deps) > 0 {
		r.SetAttr("deps", deps)
	}
}

var kinds = map[string]rule.KindInfo{
	"bzl_library": {
		NonEmptyAttrs:  map[string]bool{"srcs": true, "deps": true},
		MergeableAttrs: map[string]bool{"srcs": true},
	},
}

// GenerateRules extracts build metadata from source files in a directory.
// GenerateRules is called in each directory where an update is requested
// in depth-first post-order.
//
// args contains the arguments for GenerateRules. This is passed as a
// struct to avoid breaking implementations in the future when new
// fields are added.
//
// A GenerateResult struct is returned. Optional fields may be added to this
// type in the future.
//
// Any non-fatal errors this function encounters should be logged using
// log.Print.
func (*bzlLibraryLang) GenerateRules(args language.GenerateArgs) language.GenerateResult {
	var rules []*rule.Rule
	var imports []interface{}
	for _, f := range append(args.RegularFiles, args.GenFiles...) {
		if !isBzlSourceFile(f) {
			continue
		}
		name := strings.TrimSuffix(f, fileType)
		r := rule.NewRule("bzl_library", name)

		r.SetAttr("srcs", []string{f})

		shouldSetVisibility := args.File == nil || !args.File.HasDefaultVisibility()
		if shouldSetVisibility {
			vis := checkInternalVisibility(args.Rel, "//visibility:public")
			r.SetAttr("visibility", []string{vis})
		}

		fullPath := filepath.Join(args.Dir, f)
		loads, err := getBzlFileLoads(fullPath)
		if err != nil {
			log.Printf("%s: contains syntax errors: %v", fullPath, err)
			// Don't `continue` since it is reasonable to create a target even
			// without deps.
		}

		rules = append(rules, r)
		imports = append(imports, loads)
	}

	return language.GenerateResult{
		Gen:     rules,
		Imports: imports,
		Empty:   generateEmpty(args),
	}
}

func getBzlFileLoads(path string) ([]string, error) {
	f, err := os.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("os.ReadFile(%q) error: %v", path, err)
	}
	ast, err := build.ParseBuild(path, f)
	if err != nil {
		return nil, fmt.Errorf("build.Parse(%q) error: %v", f, err)
	}

	var loads []string
	build.WalkOnce(ast, func(expr *build.Expr) {
		n := *expr
		if l, ok := n.(*build.LoadStmt); ok {
			loads = append(loads, l.Module.Value)
		}
	})
	sort.Strings(loads)

	return loads, nil
}

func isBzlSourceFile(f string) bool {
	return strings.HasSuffix(f, fileType) && !ignoreSuffix.Matches(f)
}

// generateEmpty generates the list of rules that don't need to exist in the
// BUILD file any more.
// For each bzl_library rule in args.File that only has srcs that aren't in
// args.RegularFiles or args.GenFiles, add a bzl_library with no srcs or deps.
// That will let Gazelle delete bzl_library rules after the corresponding .bzl
// files are deleted.
func generateEmpty(args language.GenerateArgs) []*rule.Rule {
	var ret []*rule.Rule
	if args.File == nil {
		return ret
	}
	for _, r := range args.File.Rules {
		if r.Kind() != "bzl_library" {
			continue
		}
		name := r.AttrString("name")

		exists := make(map[string]bool)
		for _, f := range args.RegularFiles {
			exists[f] = true
		}
		for _, f := range args.GenFiles {
			exists[f] = true
		}
		for _, r := range args.File.Rules {
			srcsExist := false
			for _, f := range r.AttrStrings("srcs") {
				if exists[f] {
					srcsExist = true
					break
				}
			}
			if !srcsExist {
				ret = append(ret, rule.NewRule("bzl_library", name))
			}
		}
	}
	return ret
}

type srcsList []string

func (s srcsList) Contains(m string) bool {
	for _, e := range s {
		if e == m {
			return true
		}
	}
	return false
}

// checkInternalVisibility overrides the given visibility if the package is
// internal.
func checkInternalVisibility(rel, visibility string) string {
	if i := pathtools.Index(rel, "internal"); i > 0 {
		visibility = fmt.Sprintf("//%s:__subpackages__", rel[:i-1])
	} else if i := pathtools.Index(rel, "private"); i > 0 {
		visibility = fmt.Sprintf("//%s:__subpackages__", rel[:i-1])
	} else if pathtools.HasPrefix(rel, "internal") || pathtools.HasPrefix(rel, "private") {
		visibility = "//:__subpackages__"
	}
	return visibility
}
