// 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_skvm_tests_sources = sksl_rte_tests + sksl_rte_error_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 individual targets
# instead of the monolithic ones.
skia_gpu_sources = skia_gpu_public + skia_gpu_private
skia_gl_gpu_sources = skia_gpu_gl_public + skia_gpu_gl_private + skia_gpu_chromium_public
skia_vk_sources = skia_gpu_vk_public + skia_gpu_vk_private +
                  skia_gpu_vk_chromium_public + skia_gpu_vk_chromium_private
skia_metal_sources = skia_gpu_metal_public + skia_gpu_metal_private + skia_gpu_metal_cpp
skia_dawn_sources = skia_gpu_dawn_public + skia_gpu_dawn_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)
