// Copyright 2022 The LUCI Authors.
//
// 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 base contains code shared by other CLI subpackages.
package base

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

	"github.com/bazelbuild/buildtools/build"
	"go.chromium.org/luci/common/data/stringset"
	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/common/system/filesystem"
	"go.chromium.org/luci/lucicfg/buildifier"
	"go.chromium.org/luci/lucicfg/vars"
	"google.golang.org/protobuf/encoding/prototext"
)

// ConfigName is the file name we will be used for lucicfg formatting
const ConfigName = ".lucicfgfmtrc"

// sentinel is used to prevent the walking functions in this package from walking
// across a source control boundary. As of 2023 Q1 we are only worried about Git
// repos, but should we ever support more VCS's and this walking code is still
// required (i.e. this hasn't been replaced with a WORKSPACE style config file),
// this should be extended.
var sentinel = []string{".git"}

// RewriterFactory is used to map from 'file to be formatted' to a Rewriter object,
// via its GetRewriter method.
//
// This struct is obtained via the GetRewriterFactory function.
type RewriterFactory struct {
	rules          []pathRules
	configFilePath string
}

type pathRules struct {
	path  string // absolute path to the folder where this rules applies.
	rules *buildifier.LucicfgFmtConfig_Rules
}

// CheckForBogusConfig will look for any config files contained in a subdirectory of entryPath
// (recursively).
//
// Because we intend for there to be at most one config file per workspace, and for that config
// file to be located at the root of the workspace, any such extra config files would be errors.
// Due to the 'stateless' nature of fmt and lint, we search down the directory hierarchy here to
// try to detect such misconfiguration, but in the future when these subcommands become
// stateful (like validate currently is), we may remove this check.
func CheckForBogusConfig(entryPath string) error {
	// Traverse downwards
	if err := filepath.WalkDir(entryPath, func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		// Skip checking of entry path, downwards is exclusive
		if d.IsDir() && path != entryPath {
			if _, err := os.Stat(filepath.Join(path, ConfigName)); err == nil {
				return errors.Reason(
					"\nFound a config in a subdirectory<%s> of a star file."+
						"Please move to the highest common ancestor directory - %s\n",
					path,
					entryPath).Err()
			} else if !errors.Is(err, os.ErrNotExist) {
				return err
			}
		}
		return nil
	}); err != nil {
		return err
	} else {
		return nil
	}
}

func findConfigPathUpwards(path string) (string, error) {
	var currentDir = path
	for {
		if _, err := os.Stat(filepath.Join(currentDir, ConfigName)); err == nil {
			return filepath.Join(currentDir, ConfigName), nil
		} else if !errors.Is(err, os.ErrNotExist) {
			return "", err
		} else {
			var parent = filepath.Dir(currentDir)

			if _, err := os.Stat(filepath.Join(path, ".git")); err == nil || parent == currentDir {
				return "", nil
			}

			currentDir = parent
		}
	}
}

func convertOrderingToTable(nameOrdering []string) map[string]int {
	count := len(nameOrdering)
	table := make(map[string]int, count)
	// This sequentially gives the names a priority value in the range
	// [-count, 0). This ensures that all names have distinct priority
	// values that sort them in the specified order. Since all priority
	// values are less than the default 0, all names present in the
	// ordering will sort before names that don't appear in the ordering.
	for i, n := range nameOrdering {
		table[n] = i - count
	}
	return table
}

func rewriterFromConfig(nameOrdering map[string]int) *build.Rewriter {
	var rewriter = vars.GetDefaultRewriter()
	if nameOrdering != nil {
		rewriter.NamePriority = nameOrdering
		rewriter.RewriteSet = append(rewriter.RewriteSet, "callsort")
	}
	return rewriter
}

// GetRewriterFactory will attempt to create a RewriterFactory object
//
// If configPath is empty, or points to a file which doesn't exist, the returned
// factory will just produce GetDefaultRewriter() when asked about any path.
// We will return an error if the config file is invalid.
func GetRewriterFactory(configPath string) (rewriterFactory *RewriterFactory, err error) {
	rewriterFactory = &RewriterFactory{
		rules:          []pathRules{},
		configFilePath: "",
	}
	if configPath == "" {
		return
	}
	contents, err := os.ReadFile(configPath)
	if err != nil {
		if !errors.Is(err, os.ErrNotExist) {
			fmt.Printf("Failed on reading file - %s", configPath)
			return nil, err
		} else {
			return rewriterFactory, nil
		}
	}
	luci := &buildifier.LucicfgFmtConfig{}

	if err := prototext.Unmarshal(contents, luci); err != nil {
		return nil, err
	}
	return getPostProcessedRewriterFactory(configPath, luci)
}

// getPostProcessedRewriterFactory will contain all logic used to make sure
// RewriterFactory is normalized the way we want.
//
// Currently, we will fix paths so that they are absolute.
// We will also perform a check so that there are no duplicate paths and
// all paths are delimited with "/"
func getPostProcessedRewriterFactory(configPath string, cfg *buildifier.LucicfgFmtConfig) (*RewriterFactory, error) {
	pathSet := stringset.New(0)
	rules := cfg.Rules
	rulesSlice := make([]pathRules, 0)
	for ruleIndex, rule := range rules {
		// If a rule doesn't have any paths, err out and notify users
		if len(rule.Path) == 0 {
			return nil, errors.Reason(
				"rule[%d]: Does not contain any paths",
				ruleIndex).Err()
		}
		for rulePathIndex, pathInDir := range rule.Path {
			// Fix paths. Update to use absolute path.
			fixedPathInDir := filepath.Clean(
				filepath.Join(filepath.Dir(configPath), pathInDir),
			)
			// Check for duplicate paths. If there is, return error
			if pathSet.Contains(stringset.NewFromSlice(fixedPathInDir)) {
				return nil, errors.Reason(
					"rule[%d].path[%d]: Found duplicate path '%s'",
					ruleIndex, rulePathIndex, pathInDir).Err()
			}
			// Check for backslash in path, if there is, return error
			if strings.Contains(pathInDir, "\\") {
				return nil, errors.Reason(
					"rule[%d].path[%d]: Path should not contain backslash '%s'",
					ruleIndex, rulePathIndex, pathInDir).Err()
			}
			// Add into set to check later if duplicate
			pathSet.Add(fixedPathInDir)
			if fixedPathInDirAbs, err := filepath.Abs(fixedPathInDir); err != nil {
				return nil, errors.Annotate(err, "rule[%d].path[%d]: filepath.Abs error %s",
					ruleIndex, rulePathIndex, pathInDir).Err()
			} else {
				fixedPathInDir = fixedPathInDirAbs
			}

			rulesSlice = append(rulesSlice, pathRules{
				fixedPathInDir,
				rule,
			})
		}
	}

	return &RewriterFactory{
		rulesSlice,
		filepath.Dir(configPath),
	}, nil
}

// GetRewriter will return the Rewriter which is appropriate for formatting
// the file at `path`, using the previously loaded formatting configuration.
//
// Note the method signature will pass in values that we need to evaluate
// the correct rewriter.
//
// We will accept both relative and absolute paths.
func (f *RewriterFactory) GetRewriter(path string) (*build.Rewriter, error) {
	rules := f.rules
	// Check if path is abs, if not, fix it
	if !filepath.IsAbs(path) {
		return nil, errors.Reason("GetRewriter got non-absolute path: %q", path).Err()
	}
	longestPathMatch := ""
	var matchingRule *buildifier.LucicfgFmtConfig_Rules

	// Find the path that best matches the one we are processing.
	for _, rule := range rules {
		commonAncestor, err := filesystem.GetCommonAncestor(
			[]string{rule.path, path},
			sentinel,
		)

		if err != nil {
			return nil, err
		}

		commonAncestor = filepath.Clean(commonAncestor)
		if commonAncestor == rule.path && len(commonAncestor) > len(longestPathMatch) {
			longestPathMatch = commonAncestor
			matchingRule = rule.rules
		}
	}
	if matchingRule != nil && matchingRule.FunctionArgsSort != nil {
		return rewriterFromConfig(
			convertOrderingToTable(matchingRule.FunctionArgsSort.Arg),
		), nil
	}

	return vars.GetDefaultRewriter(), nil
}

// GuessRewriterFactoryFunc will find the common ancestor dir from all given paths
// and return a func that returns the rewriter factory.
//
// Will look for a config file upwards(inclusive). If found, it will be used to determine
// rewriter properties. It will also look downwards(exclusive) to expose any misplaced
// config files.
func GuessRewriterFactoryFunc(paths []string) (*RewriterFactory, error) {
	// Find the common ancestor
	commonAncestorPath, err := filesystem.GetCommonAncestor(paths, sentinel)

	if errors.Is(err, filesystem.ErrRootSentinel) {
		// we hit the repo root, just return function that returns default rewriter
		rewriterFactory, err := GetRewriterFactory("")
		if err != nil {
			return nil, err
		}
		return rewriterFactory, nil
	}
	if err != nil {
		// other errors are fatal
		return nil, err
	}
	if err := CheckForBogusConfig(commonAncestorPath); err != nil {
		return nil, err
	}

	luciConfigPath, err := findConfigPathUpwards(commonAncestorPath)
	if err != nil {
		return nil, err
	}
	rewriterFactory, err := GetRewriterFactory(luciConfigPath)
	if err != nil {
		return nil, err
	}

	return rewriterFactory, nil
}
