/* 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"
	"io/ioutil"
	"log"
	"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, 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 hte target name should be.
			deps = append(deps, strings.TrimSuffix(imp, fileType))
			continue
		}

		res := resolve.ImportSpec{
			Lang: languageName,
			Imp:  impLabel.String(),
		}
		matches := ix.FindRulesByImport(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 := ioutil.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("ioutil.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
}
