// 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 (
	"fmt"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"

	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/util"
	"go.skia.org/skia/bazel/exporter/build_proto/analysis_v2"
	"go.skia.org/skia/bazel/exporter/build_proto/build"
)

const (
	ruleOnlyRepoPattern = `^(@\w+)$`
	rulePattern         = `^(?P<repo>@[^/]+)?/(?P<path>[^:]+)(?P<target>:[^:]+)?$`
	locationPattern     = `^(?P<path>[^:]+):(?P<line>[^:]+):(?P<pos>[^:]+)$`
)

var (
	ruleOnlyRepoRegex = regexp.MustCompile(ruleOnlyRepoPattern)
	ruleRegex         = regexp.MustCompile(rulePattern)
	locRegex          = regexp.MustCompile(locationPattern)
)

// Return true if the given rule name represents an external repository.
func isExternalRule(name string) bool {
	return name[0] == '@'
}

// Given a Bazel rule name find that rule from within the
// query results.
func findRule(qr *analysis_v2.CqueryResult, name string) (*build.Rule, error) {
	for _, result := range qr.GetResults() {
		r := result.GetTarget().GetRule()
		if r.GetName() == name {
			return r, nil
		}
	}
	return nil, skerr.Fmt(`cannot find rule %q`, name)
}

// Parse a rule into its constituent parts.
// https://docs.bazel.build/versions/main/guide.html#specifying-targets-to-build
func parseRule(rule string) (repo string, path string, target string, err error) {
	match := ruleOnlyRepoRegex.FindStringSubmatch(rule)
	if match != nil {
		return match[1], "/", strings.TrimPrefix(match[1], "@"), nil
	}

	match = ruleRegex.FindStringSubmatch(rule)
	if match == nil {
		return "", "", "", skerr.Fmt(`Unable to match rule %q`, rule)
	}

	if len(match[3]) > 0 {
		target = strings.TrimPrefix(match[3], ":")
	} else {
		// No explicit target, so use directory name as default target.
		target = filepath.Base(match[2])
	}

	return match[1], match[2], target, nil
}

// Parse a file location into its three constituent parts.
//
// A location is of the form:
//
//	/full/path/to/BUILD.bazel:33:20
func parseLocation(location string) (path string, line int, pos int, err error) {
	match := locRegex.FindStringSubmatch(location)
	if match == nil {
		return "", 0, 0, skerr.Fmt(`unable to match file location %q`, location)
	}
	path = match[1]
	line, err = strconv.Atoi(match[2])
	if err != nil {
		return "", 0, 0, skerr.Fmt(`unable to parse line no. %q`, match[2])
	}
	pos, err = strconv.Atoi(match[3])
	if err != nil {
		return "", 0, 0, skerr.Fmt(`unable to parse pos. %q`, match[3])
	}
	return path, line, pos, nil
}

// Return the directory containing the file in the location string.
func getLocationDir(location string) (string, error) {
	filePath, _, _, err := parseLocation(location)
	if err != nil {
		return "", skerr.Wrap(err)
	}
	return filepath.Dir(filePath), nil
}

func makeCanonicalRuleName(bazelRuleName string) (string, error) {
	repo, path, target, err := parseRule(bazelRuleName)
	if err != nil {
		return "", skerr.Wrap(err)
	}
	return fmt.Sprintf("%s/%s:%s", repo, path, target), nil
}

// Determine if a target refers to a file, or a rule. target is of
// the form:
//
// file: //include/private:SingleOwner.h
// rule: //bazel/common_config_settings:has_gpu_backend
func isFileTarget(target string) bool {
	_, _, target, err := parseRule(target)
	if err != nil {
		return false
	}
	return strings.Contains(target, ".")
}

// Create a string that uniquely identifies the rule and can be used
// in the exported project file as a valid name.
func getRuleSimpleName(bazelRuleName string) (string, error) {
	s, err := makeCanonicalRuleName(bazelRuleName)
	if err != nil {
		return "", skerr.Wrap(err)
	}
	s = strings.TrimPrefix(s, "//:")
	s = strings.TrimPrefix(s, "//")
	s = strings.ReplaceAll(s, "//", "_")
	s = strings.ReplaceAll(s, "@", "at_")
	s = strings.ReplaceAll(s, "/", "_")
	s = strings.ReplaceAll(s, ":", "_")
	s = strings.ReplaceAll(s, "__", "_")
	return s, nil
}

// Append all elements to the slice if not already present in the slice.
func appendUnique(slice []string, elems ...string) []string {
	for _, elem := range elems {
		if !util.In(elem, slice) {
			slice = append(slice, elem)
		}
	}
	return slice
}

// Retrieve (if present) a slice of string attribute values from the given
// rule and attribute name. A nil slice will be returned if the attribute
// does not exist in the rule. A slice of strings (possibly empty) will be
// returned if the attribute is empty. An error will be returned if the
// attribute is not a list type.
func getRuleStringArrayAttribute(r *build.Rule, name string) ([]string, error) {
	for _, attrib := range r.Attribute {
		if attrib.GetName() != name {
			continue
		}
		if attrib.GetType() != build.Attribute_LABEL_LIST &&
			attrib.GetType() != build.Attribute_STRING_LIST {
			return nil, skerr.Fmt(`%s in rule %q is not a list`, name, r.GetName())
		}
		return attrib.GetStringListValue(), nil
	}
	return nil, nil
}
