// Copyright 2022 Google LLC
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package exporter

import (
	"bytes"
	"fmt"
	"path/filepath"
	"regexp"
	"sort"
	"strings"

	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/util"
	"go.skia.org/skia/bazel/exporter/build_proto/build"
	"go.skia.org/skia/bazel/exporter/interfaces"
	"google.golang.org/protobuf/proto"
)

// The contents (or partial contents) of a GNI file.
type gniFileContents struct {
	hasSrcs     bool            // Has at least one file in $_src/ dir?
	hasIncludes bool            // Has at least one file in $_include/ dir?
	hasModules  bool            // Has at least one file in $_module/ dir?
	bazelFiles  map[string]bool // Set of Bazel files generating GNI contents.
	data        []byte          // The file contents to be written.
}

// GNIFileListExportDesc contains a description of the data that
// will comprise a GN file list variable when written to a *.gni file.
type GNIFileListExportDesc struct {
	// The file list variable name to use in the exported *.gni file.
	// In the *.gni file this will look like:
	//   var_name = [ ... ]
	Var string
	// The Bazel rule name(s) to export into the file list.
	Rules []string
}

// GNIExportDesc defines a GNI file to be exported, the rules to be
// exported, and the file list variable names in which to list the
// rule files.
type GNIExportDesc struct {
	GNI  string                  // The export destination *.gni file path (relative to workspace).
	Vars []GNIFileListExportDesc // List of GNI file list variable rules.
}

// GNIExporterParams contains the construction parameters when
// creating a new GNIExporter via NewGNIExporter().
type GNIExporterParams struct {
	WorkspaceDir string          // The Bazel workspace directory path.
	ExportDescs  []GNIExportDesc // The Bazel rules to export.
}

// GNIExporter is an object responsible for exporting rules defined in a
// Bazel workspace to file lists in GNI format (GN's *.gni files). This exporter
// is tightly coupled to the Skia Bazel rules and GNI configuration.
type GNIExporter struct {
	workspaceDir   string                // The Bazel workspace path.
	fs             interfaces.FileSystem // For filesystem interactions.
	exportGNIDescs []GNIExportDesc       // The rules to export.
}

// Skia source files which are deprecated. These are omitted from
// *.gni files during export because the skia.h file is a generated
// file and it cannot include deprecated files without breaking
// clients that include it.
var deprecatedFiles = []string{
	"include/core/SkDrawLooper.h",
	"include/effects/SkBlurDrawLooper.h",
	"include/effects/SkLayerDrawLooper.h",
}

// The footer written to gn/core.gni.
const coreGNIFooter = `skia_core_sources += skia_pathops_sources
skia_core_sources += skia_skpicture_sources

skia_core_public += skia_pathops_public
skia_core_public += skia_skpicture_public
# TODO(kjlubick) Move this into Chromium's BUILD.gn file.
skia_core_public += skia_discardable_memory_chromium
`

// The footer written to gn/sksl_tests.gni.
const skslTestsFooter = `sksl_glsl_tests_sources =
    sksl_error_tests + sksl_glsl_tests + sksl_inliner_tests +
    sksl_folding_tests + sksl_shared_tests +
    sksl_inverse_hyperbolic_intrinsics_tests

sksl_glsl_settings_tests_sources = sksl_blend_tests + sksl_settings_tests

sksl_metal_tests_sources =
    sksl_metal_tests + sksl_blend_tests + sksl_shared_tests +
    sksl_inverse_hyperbolic_intrinsics_tests

sksl_hlsl_tests_sources = sksl_blend_tests + sksl_shared_tests

sksl_wgsl_tests_sources = sksl_wgsl_tests

sksl_spirv_tests_sources =
    sksl_blend_tests + sksl_shared_tests +
    sksl_inverse_hyperbolic_intrinsics_tests + sksl_spirv_tests

sksl_skrp_tests_sources = sksl_folding_tests + sksl_rte_tests + sksl_shared_tests

sksl_stage_tests_sources = sksl_rte_tests

sksl_minify_tests_sources = sksl_rte_tests + sksl_folding_tests`

// The footer written to modules/skshaper/skshaper.gni.
const skshaperFooter = `
declare_args() {
  skia_enable_skshaper = true
}
declare_args() {
  skia_enable_skshaper_tests = skia_enable_skshaper
}`

// The footer written to gn/gpu.gni.
const gpuGNIFooter = `
# TODO(kjlubick) Update clients to use the targets with updated names
skia_gpu_private = skia_ganesh_private
`

// The footer written to gn/utils.gni.
const utilsGNIFooter = `
# TODO(kjlubick) Update pdfium to use the individual target
# instead of the monolithic ones.
skia_utils_sources = skia_utils_private + skia_utils_chromium
`

// Map of GNI file names to footer text to be appended to the end of the file.
var footerMap = map[string]string{
	"gn/core.gni":                   coreGNIFooter,
	"gn/gpu.gni":                    gpuGNIFooter,
	"gn/sksl_tests.gni":             skslTestsFooter,
	"gn/utils.gni":                  utilsGNIFooter,
	"modules/skshaper/skshaper.gni": skshaperFooter,
}

// Match variable definition of a list in a *.gni file. For example:
//
//	foo = []
//
// will match "foo"
var gniVariableDefReg = regexp.MustCompile(`^(\w+)\s?=\s?\[`)

// NewGNIExporter creates an exporter that will export to GN's (*.gni) files.
func NewGNIExporter(params GNIExporterParams, filesystem interfaces.FileSystem) *GNIExporter {
	e := &GNIExporter{
		workspaceDir:   params.WorkspaceDir,
		fs:             filesystem,
		exportGNIDescs: params.ExportDescs,
	}
	return e
}

func makeGniFileContents() gniFileContents {
	return gniFileContents{
		bazelFiles: make(map[string]bool),
	}
}

// Given a Bazel rule name find that rule from within the
// query results. Returns nil if the given rule is not present.
func findQueryResultRule(qr *build.QueryResult, name string) *build.Rule {
	for _, target := range qr.GetTarget() {
		r := target.GetRule()
		if r.GetName() == name {
			return r
		}
	}
	return nil
}

// Given a relative path to a file return the relative path to the
// top directory (in our case the workspace). For example:
//
//	getPathToTopDir("path/to/file.h") -> "../.."
//
// The paths are to be delimited by forward slashes ('/') - even on
// Windows.
func getPathToTopDir(path string) string {
	if filepath.IsAbs(path) {
		return ""
	}
	d, _ := filepath.Split(path)
	if d == "" {
		return "."
	}
	d = strings.TrimSuffix(d, "/")
	items := strings.Split(d, "/")
	var sb = strings.Builder{}
	for i := 0; i < len(items); i++ {
		if i > 0 {
			sb.WriteString("/")
		}
		sb.WriteString("..")
	}
	return sb.String()
}

// Retrieve all rule attributes which are internal file targets.
func getRuleFiles(r *build.Rule, attrName string) ([]string, error) {
	items, err := getRuleStringArrayAttribute(r, attrName)
	if err != nil {
		return nil, skerr.Wrap(err)
	}

	var files []string
	for _, item := range items {
		if !isExternalRule(item) && isFileTarget(item) {
			files = append(files, item)
		}
	}
	return files, nil
}

// Convert a file path into a workspace relative path using variables to
// specify the base folder. The variables are one of $_src, $_include, or $_modules.
func makeRelativeFilePathForGNI(path string) (string, error) {
	if strings.HasPrefix(path, "src/") {
		return "$_src/" + strings.TrimPrefix(path, "src/"), nil
	}
	if strings.HasPrefix(path, "include/") {
		return "$_include/" + strings.TrimPrefix(path, "include/"), nil
	}
	if strings.HasPrefix(path, "modules/") {
		return "$_modules/" + strings.TrimPrefix(path, "modules/"), nil
	}
	// These sksl tests are purposely listed as a relative path underneath resources/sksl because
	// that relative path is re-used by the GN logic to put stuff under //tests/sksl as well.
	if strings.HasPrefix(path, "resources/sksl/") {
		return strings.TrimPrefix(path, "resources/sksl/"), nil
	}

	return "", skerr.Fmt("can't find path for %q\n", path)
}

// Convert a slice of workspace relative paths into a new slice containing
// GNI variables ($_src, $_include, etc.). *All* paths in the supplied
// slice must be a supported top-level directory.
func addGNIVariablesToWorkspacePaths(paths []string) ([]string, error) {
	vars := make([]string, 0, len(paths))
	for _, path := range paths {
		withVar, err := makeRelativeFilePathForGNI(path)
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		vars = append(vars, withVar)
	}
	return vars, nil
}

// Is the file path a C++ header?
func isHeaderFile(path string) bool {
	ext := strings.ToLower(filepath.Ext(path))
	return ext == ".h" || ext == ".hpp"
}

// Does the list of file paths contain only header files?
func fileListContainsOnlyCppHeaderFiles(files []string) bool {
	for _, f := range files {
		if !isHeaderFile(f) {
			return false
		}
	}
	return len(files) > 0 // Empty list is false, else all are headers.
}

// Write the *.gni file header.
func writeGNFileHeader(writer interfaces.Writer, gniFile *gniFileContents, pathToWorkspace string) {
	fmt.Fprintln(writer, "# DO NOT EDIT: This is a generated file.")
	fmt.Fprintln(writer, "# See //bazel/exporter_tool/README.md for more information.")

	fmt.Fprintln(writer, "#")
	if len(gniFile.bazelFiles) > 1 {
		keys := make([]string, 0, len(gniFile.bazelFiles))
		fmt.Fprintln(writer, "# The sources of truth are:")
		for bazelPath, _ := range gniFile.bazelFiles {
			keys = append(keys, bazelPath)
		}
		sort.Strings(keys)
		for _, wsPath := range keys {
			fmt.Fprintf(writer, "#   //%s\n", wsPath)
		}
	} else {
		for bazelPath, _ := range gniFile.bazelFiles {
			fmt.Fprintf(writer, "# The source of truth is //%s\n", bazelPath)
		}
	}

	writer.WriteString("\n")
	fmt.Fprintln(writer, "# To update this file, run make -C bazel generate_gni")

	writer.WriteString("\n")
	if gniFile.hasSrcs {
		fmt.Fprintf(writer, "_src = get_path_info(\"%s/src\", \"abspath\")\n", pathToWorkspace)
	}
	if gniFile.hasIncludes {
		fmt.Fprintf(writer, "_include = get_path_info(\"%s/include\", \"abspath\")\n", pathToWorkspace)
	}
	if gniFile.hasModules {
		fmt.Fprintf(writer, "_modules = get_path_info(\"%s/modules\", \"abspath\")\n", pathToWorkspace)
	}
}

// removeDuplicates returns the list of files after it has been sorted and
// all duplicate values have been removed.
func removeDuplicates(files []string) []string {
	if len(files) <= 1 {
		return files
	}
	sort.Strings(files)
	rv := make([]string, 0, len(files))
	rv = append(rv, files[0])
	for _, f := range files {
		if rv[len(rv)-1] != f {
			rv = append(rv, f)
		}
	}
	return rv
}

// Retrieve all sources ("srcs" attribute) and headers ("hdrs" attribute)
// and return as a single slice of target names. Slice entries will be
// something like:
//
//	"//src/core/file.cpp".
func getSrcsAndHdrs(r *build.Rule) ([]string, error) {
	srcs, err := getRuleFiles(r, "srcs")
	if err != nil {
		return nil, skerr.Wrap(err)
	}

	hdrs, err := getRuleFiles(r, "hdrs")
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return append(srcs, hdrs...), nil
}

// Convert a slice of file path targets to workspace relative file paths.
// i.e. convert each element like:
//
//	"//src/core/file.cpp"
//
// into:
//
//	"src/core/file.cpp"
func convertTargetsToFilePaths(targets []string) ([]string, error) {
	paths := make([]string, 0, len(targets))
	for _, target := range targets {
		path, err := getFilePathFromFileTarget(target)
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		paths = append(paths, path)
	}
	return paths, nil
}

// Is the source file deprecated? i.e. should the file be exported to projects
// generated by this package?
func isSourceFileDeprecated(workspacePath string) bool {
	return util.In(workspacePath, deprecatedFiles)
}

// Filter all deprecated files from the |files| slice, returning a new slice
// containing no deprecated files. All paths in |files| must be workspace-relative
// paths.
func filterDeprecatedFiles(files []string) []string {
	filtered := make([]string, 0, len(files))
	for _, path := range files {
		if !isSourceFileDeprecated(path) {
			filtered = append(filtered, path)
		}
	}
	return filtered
}

// Return the top-level component (directory or file) of a relative file path.
// The paths are assumed to be delimited by forward slash (/) characters (even on Windows).
// An empty string is returned if no top level folder can be found.
//
// Example:
//
//	"foo/bar/baz.txt" returns "foo"
func extractTopLevelFolder(path string) string {
	parts := strings.Split(path, "/")
	if len(parts) > 0 {
		return parts[0]
	}
	return ""
}

// Extract the name of a variable assignment from a line of text from a GNI file.
// So, a line like:
//
//	"foo = [...]"
//
// will return:
//
//	"foo"
func getGNILineVariable(line string) string {
	if matches := gniVariableDefReg.FindStringSubmatch(line); matches != nil {
		return matches[1]
	}
	return ""
}

// Given a workspace relative path return an absolute path.
func (e *GNIExporter) workspaceToAbsPath(wsPath string) string {
	if filepath.IsAbs(wsPath) {
		panic("filepath already absolute")
	}
	return filepath.Join(e.workspaceDir, wsPath)
}

// Given an absolute path return a workspace relative path.
func (e *GNIExporter) absToWorkspacePath(absPath string) (string, error) {
	if !filepath.IsAbs(absPath) {
		return "", skerr.Fmt(`"%s" is not an absolute path`, absPath)
	}
	if absPath == e.workspaceDir {
		return "", nil
	}
	wsDir := e.workspaceDir + "/"
	if !strings.HasPrefix(absPath, wsDir) {
		return "", skerr.Fmt(`"%s" is not in the workspace "%s"`, absPath, wsDir)
	}
	return strings.TrimPrefix(absPath, wsDir), nil
}

// Merge the another file contents object into this one.
func (c *gniFileContents) merge(other gniFileContents) {
	if other.hasIncludes {
		c.hasIncludes = true
	}
	if other.hasModules {
		c.hasModules = true
	}
	if other.hasSrcs {
		c.hasSrcs = true
	}
	for path, _ := range other.bazelFiles {
		c.bazelFiles[path] = true
	}
	c.data = append(c.data, other.data...)
}

// Convert all rules that go into a GNI file list.
func (e *GNIExporter) convertGNIFileList(desc GNIFileListExportDesc, qr *build.QueryResult) (gniFileContents, error) {
	var rules []string
	fileContents := makeGniFileContents()
	var targets []string
	for _, ruleName := range desc.Rules {
		r := findQueryResultRule(qr, ruleName)
		if r == nil {
			return gniFileContents{}, skerr.Fmt("Cannot find rule %s", ruleName)
		}
		absBazelPath, _, _, err := parseLocation(*r.Location)
		if err != nil {
			return gniFileContents{}, skerr.Wrap(err)
		}
		wsBazelpath, err := e.absToWorkspacePath(absBazelPath)
		if err != nil {
			return gniFileContents{}, skerr.Wrap(err)
		}
		fileContents.bazelFiles[wsBazelpath] = true
		t, err := getSrcsAndHdrs(r)
		if err != nil {
			return gniFileContents{}, skerr.Wrap(err)
		}
		if len(t) == 0 {
			return gniFileContents{}, skerr.Fmt("No files to export in rule %s", ruleName)
		}
		targets = append(targets, t...)
		rules = append(rules, ruleName)
	}

	files, err := convertTargetsToFilePaths(targets)
	if err != nil {
		return gniFileContents{}, skerr.Wrap(err)
	}

	files = filterDeprecatedFiles(files)

	files, err = addGNIVariablesToWorkspacePaths(files)
	if err != nil {
		return gniFileContents{}, skerr.Wrap(err)
	}

	files = removeDuplicates(files)

	for i := range files {
		if strings.HasPrefix(files[i], "$_src/") {
			fileContents.hasSrcs = true
		} else if strings.HasPrefix(files[i], "$_include/") {
			fileContents.hasIncludes = true
		} else if strings.HasPrefix(files[i], "$_modules/") {
			fileContents.hasModules = true
		}
	}

	var contents bytes.Buffer

	if len(rules) > 1 {
		fmt.Fprintln(&contents, "# List generated by Bazel rules:")
		for _, bazelFile := range rules {
			fmt.Fprintf(&contents, "#  %s\n", bazelFile)
		}
	} else {
		fmt.Fprintf(&contents, "# Generated by Bazel rule %s\n", rules[0])
	}
	fmt.Fprintf(&contents, "%s = [\n", desc.Var)

	for _, target := range files {
		fmt.Fprintf(&contents, "  %q,\n", target)
	}
	fmt.Fprintln(&contents, "]")
	fmt.Fprintln(&contents)
	fileContents.data = contents.Bytes()

	return fileContents, nil
}

// Export all Bazel rules to a single *.gni file.
func (e *GNIExporter) exportGNIFile(gniExportDesc GNIExportDesc, qr *build.QueryResult) error {
	// Keep the contents of each file list in memory before writing to disk.
	// This is done so that we know what variables to define for each of the
	// file lists. i.e. $_src, $_include, etc.
	gniFileContents := makeGniFileContents()
	for _, varDesc := range gniExportDesc.Vars {
		fileListContents, err := e.convertGNIFileList(varDesc, qr)
		if err != nil {
			return skerr.Wrap(err)
		}
		gniFileContents.merge(fileListContents)
	}

	writer, err := e.fs.OpenFile(e.workspaceToAbsPath(gniExportDesc.GNI))
	if err != nil {
		return skerr.Wrap(err)
	}

	pathToWorkspace := getPathToTopDir(gniExportDesc.GNI)
	writeGNFileHeader(writer, &gniFileContents, pathToWorkspace)
	writer.WriteString("\n")

	_, err = writer.Write(gniFileContents.data)
	if err != nil {
		return skerr.Wrap(err)
	}

	for gniPath, footer := range footerMap {
		if gniExportDesc.GNI == gniPath {
			fmt.Fprintln(writer, footer)
			break
		}
	}

	return nil
}

// Export the contents of a Bazel query response to one or more GNI
// files.
//
// The Bazel data to export, and the destination GNI files are defined
// by the configuration data supplied to NewGNIExporter().
func (e *GNIExporter) Export(qcmd interfaces.QueryCommand) error {
	in, err := qcmd.Read()
	if err != nil {
		return skerr.Wrapf(err, "error reading bazel cquery data")
	}
	qr := &build.QueryResult{}
	if err := proto.Unmarshal(in, qr); err != nil {
		return skerr.Wrapf(err, "failed to unmarshal cquery result")
	}
	for _, desc := range e.exportGNIDescs {
		err = e.exportGNIFile(desc, qr)
		if err != nil {
			return skerr.Wrap(err)
		}
	}
	return nil
}

// Make sure GNIExporter fulfills the Exporter interface.
var _ interfaces.Exporter = (*GNIExporter)(nil)
