/*
Package crosstooltostarlarklib provides the Transform method
for conversion of a CROSSTOOL file to a Starlark rule.

https://github.com/bazelbuild/bazel/issues/5380
*/
package crosstooltostarlarklib

import (
	"bytes"
	"errors"
	"fmt"
	"sort"
	"strings"

	crosstoolpb "third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config_go_proto"
)

// CToolchainIdentifier is what we'll use to differ between CToolchains
// If a CToolchain can be distinguished from the other CToolchains
// by only one of the fields (eg if cpu is different for each CToolchain
// then only that field will be set.
type CToolchainIdentifier struct {
	cpu      string
	compiler string
}

// Writes the load statement for the cc_toolchain_config_lib
func getCcToolchainConfigHeader() string {
	return `load("//tools/cpp:cc_toolchain_config_lib.bzl",
    "action_config",
    "artifact_name_pattern",
    "env_entry",
    "env_set",
    "feature",
    "feature_set",
    "flag_group",
    "flag_set",
    "make_variable",
    "tool",
    "tool_path",
    "variable_with_value",
    "with_feature_set",
)
`
}

var allCompileActions = []string{
	"c-compile",
	"c++-compile",
	"linkstamp-compile",
	"assemble",
	"preprocess-assemble",
	"c++-header-parsing",
	"c++-module-compile",
	"c++-module-codegen",
	"clif-match",
	"lto-backend",
}

var allCppCompileActions = []string{
	"c++-compile",
	"linkstamp-compile",
	"c++-header-parsing",
	"c++-module-compile",
	"c++-module-codegen",
	"clif-match",
}

var preprocessorCompileActions = []string{
	"c-compile",
	"c++-compile",
	"linkstamp-compile",
	"preprocess-assemble",
	"c++-header-parsing",
	"c++-module-compile",
	"clif-match",
}

var codegenCompileActions = []string{
	"c-compile",
	"c++-compile",
	"linkstamp-compile",
	"assemble",
	"preprocess-assemble",
	"c++-module-codegen",
	"lto-backend",
}

var allLinkActions = []string{
	"c++-link-executable",
	"c++-link-dynamic-library",
	"c++-link-nodeps-dynamic-library",
}

var actionNames = map[string]string{
	"c-compile":                       "ACTION_NAMES.c_compile",
	"c++-compile":                     "ACTION_NAMES.cpp_compile",
	"linkstamp-compile":               "ACTION_NAMES.linkstamp_compile",
	"cc-flags-make-variable":          "ACTION_NAMES.cc_flags_make_variable",
	"c++-module-codegen":              "ACTION_NAMES.cpp_module_codegen",
	"c++-header-parsing":              "ACTION_NAMES.cpp_header_parsing",
	"c++-module-compile":              "ACTION_NAMES.cpp_module_compile",
	"assemble":                        "ACTION_NAMES.assemble",
	"preprocess-assemble":             "ACTION_NAMES.preprocess_assemble",
	"lto-indexing":                    "ACTION_NAMES.lto_indexing",
	"lto-backend":                     "ACTION_NAMES.lto_backend",
	"c++-link-executable":             "ACTION_NAMES.cpp_link_executable",
	"c++-link-dynamic-library":        "ACTION_NAMES.cpp_link_dynamic_library",
	"c++-link-nodeps-dynamic-library": "ACTION_NAMES.cpp_link_nodeps_dynamic_library",
	"c++-link-static-library":         "ACTION_NAMES.cpp_link_static_library",
	"strip":                           "ACTION_NAMES.strip",
	"objc-compile":                    "ACTION_NAMES.objc_compile",
	"objc++-compile":                  "ACTION_NAMES.objcpp_compile",
	"clif-match":                      "ACTION_NAMES.clif_match",
// 	"objcopy_embed_data":              "ACTION_NAMES.objcopy_embed_data", // copybara-comment-this-out-please
// 	"ld_embed_data":                   "ACTION_NAMES.ld_embed_data",      // copybara-comment-this-out-please
}

func getLoadActionsStmt() string {
	return "load(\"@bazel_tools//tools/build_defs/cc:action_names.bzl\", \"ACTION_NAMES\")\n\n"
}

// Returns a map {toolchain_identifier : CToolchainIdentifier}
func toolchainToCToolchainIdentifier(
	crosstool *crosstoolpb.CrosstoolRelease) map[string]CToolchainIdentifier {
	cpuToCompiler := make(map[string][]string)
	compilerToCPU := make(map[string][]string)
	var cpus []string
	var compilers []string
	var identifiers []string
	res := make(map[string]CToolchainIdentifier)
	for _, cToolchain := range crosstool.GetToolchain() {
		cpu := cToolchain.GetTargetCpu()
		compiler := cToolchain.GetCompiler()

		cpuToCompiler[cpu] = append(cpuToCompiler[cpu], compiler)
		compilerToCPU[compiler] = append(compilerToCPU[compiler], cpu)

		cpus = append(cpus, cToolchain.GetTargetCpu())
		compilers = append(compilers, cToolchain.GetCompiler())
		identifiers = append(identifiers, cToolchain.GetToolchainIdentifier())
	}

	for i := range cpus {
		if len(cpuToCompiler[cpus[i]]) == 1 {
			// if cpu is unique among CToolchains, we don't need the compiler field
			res[identifiers[i]] = CToolchainIdentifier{cpu: cpus[i], compiler: ""}
		} else {
			res[identifiers[i]] = CToolchainIdentifier{
				cpu:      cpus[i],
				compiler: compilers[i],
			}
		}
	}
	return res
}

func getConditionStatementForCToolchainIdentifier(identifier CToolchainIdentifier) string {
	if identifier.compiler != "" {
		return fmt.Sprintf(
			"ctx.attr.cpu == \"%s\" and ctx.attr.compiler == \"%s\"",
			identifier.cpu,
			identifier.compiler)
	}
	return fmt.Sprintf("ctx.attr.cpu == \"%s\"", identifier.cpu)
}

func isArrayPrefix(prefix []string, arr []string) bool {
	if len(prefix) > len(arr) {
		return false
	}
	for i := 0; i < len(prefix); i++ {
		if arr[i] != prefix[i] {
			return false
		}
	}
	return true
}

func isAllCompileActions(actions []string) (bool, []string) {
	if isArrayPrefix(allCompileActions, actions) {
		return true, actions[len(allCompileActions):]
	}
	return false, actions
}

func isAllCppCompileActions(actions []string) (bool, []string) {
	if isArrayPrefix(allCppCompileActions, actions) {
		return true, actions[len(allCppCompileActions):]
	}
	return false, actions
}

func isPreprocessorCompileActions(actions []string) (bool, []string) {
	if isArrayPrefix(preprocessorCompileActions, actions) {
		return true, actions[len(preprocessorCompileActions):]
	}
	return false, actions
}

func isCodegenCompileActions(actions []string) (bool, []string) {
	if isArrayPrefix(codegenCompileActions, actions) {
		return true, actions[len(codegenCompileActions):]
	}
	return false, actions
}

func isAllLinkActions(actions []string) (bool, []string) {
	if isArrayPrefix(allLinkActions, actions) {
		return true, actions[len(allLinkActions):]
	}
	return false, actions
}

func getActionNames(actions []string) []string {
	var res []string
	for _, el := range actions {
		if name, ok := actionNames[el]; ok {
			res = append(res, name)
		} else {
			res = append(res, "\""+el+"\"")
		}
	}
	return res
}

func getListOfActions(name string, depth int) string {
	var res []string
	if name == "all_compile_actions" {
		res = getActionNames(allCompileActions)
	} else if name == "all_cpp_compile_actions" {
		res = getActionNames(allCppCompileActions)
	} else if name == "preprocessor_compile_actions" {
		res = getActionNames(preprocessorCompileActions)
	} else if name == "codegen_compile_actions" {
		res = getActionNames(codegenCompileActions)
	} else if name == "all_link_actions" {
		res = getActionNames(allLinkActions)
	}
	stmt := fmt.Sprintf("%s%s = %s\n\n", getTabs(depth),
		name, makeStringArr(res, depth /* isPlainString= */, false))
	return stmt
}

func processActions(actions []string, depth int) []string {
	var res []string
	var ok bool
	initLen := len(actions)
	if ok, actions = isAllCompileActions(actions); ok {
		res = append(res, "all_compile_actions")
	}
	if ok, actions = isAllCppCompileActions(actions); ok {
		res = append(res, "all_cpp_compile_actions")
	}
	if ok, actions = isPreprocessorCompileActions(actions); ok {
		res = append(res, "preprocessor_compile_actions")
	}
	if ok, actions = isCodegenCompileActions(actions); ok {
		res = append(res, "codegen_actions")
	}
	if ok, actions = isAllLinkActions(actions); ok {
		res = append(res, "all_link_actions")
	}
	if len(actions) != 0 {
		actions = getActionNames(actions)
		newDepth := depth + 1
		if len(actions) != initLen {
			newDepth++
		}
		res = append(res, makeStringArr(actions, newDepth /* isPlainString= */, false))
	}
	return res
}

func getRule(cToolchainIdentifiers map[string]CToolchainIdentifier) string {
	cpus := make(map[string]bool)
	compilers := make(map[string]bool)
	for _, val := range cToolchainIdentifiers {
		cpus[val.cpu] = true
		if val.compiler != "" {
			compilers[val.compiler] = true
		}
	}

	var cpuValues []string
	for cpu := range cpus {
		cpuValues = append(cpuValues, cpu)
	}

	var compilerValues []string
	for compiler := range compilers {
		compilerValues = append(compilerValues, compiler)
	}
	var args []string
	sort.Strings(cpuValues)
	args = append(args,
		fmt.Sprintf(
			`"cpu": attr.string(mandatory=True, values=["%s"]),`,
			strings.Join(cpuValues, "\", \"")))
	if len(compilerValues) != 0 {
		sort.Strings(compilerValues)
		args = append(args,
			fmt.Sprintf(`"compiler": attr.string(values=["%s"]),`,
				strings.Join(compilerValues, "\", \"")))
	}
	return fmt.Sprintf(`cc_toolchain_config_rule =  rule(
    implementation = _impl,
    attrs = {
        %s
    },
    provides = [CcToolchainConfigInfo],
    executable = True,
)
`, strings.Join(args, "\n        "))
}

func getImplHeader() string {
	return "def _impl(ctx):\n"
}

func getStringStatement(crosstool *crosstoolpb.CrosstoolRelease,
	cToolchainIdentifiers map[string]CToolchainIdentifier, field string,
	depth int) string {

	identifiers := getToolchainIdentifiers(crosstool)
	var fieldValues []string
	if field == "toolchain_identifier" {
		fieldValues = getToolchainIdentifiers(crosstool)
	} else if field == "host_system_name" {
		fieldValues = getHostSystemNames(crosstool)
	} else if field == "target_system_name" {
		fieldValues = getTargetSystemNames(crosstool)
	} else if field == "target_cpu" {
		fieldValues = getTargetCpus(crosstool)
	} else if field == "target_libc" {
		fieldValues = getTargetLibcs(crosstool)
	} else if field == "compiler" {
		fieldValues = getCompilers(crosstool)
	} else if field == "abi_version" {
		fieldValues = getAbiVersions(crosstool)
	} else if field == "abi_libc_version" {
		fieldValues = getAbiLibcVersions(crosstool)
	} else if field == "cc_target_os" {
		fieldValues = getCcTargetOss(crosstool)
	} else if field == "builtin_sysroot" {
		fieldValues = getBuiltinSysroots(crosstool)
	}

	mappedValuesToIds := getMappedStringValuesToIdentifiers(identifiers, fieldValues)
	return getAssignmentStatement(field, mappedValuesToIds, crosstool,
		cToolchainIdentifiers, depth /* isPlainString= */, true /* shouldFail= */, true)
}

func getFeatures(crosstool *crosstoolpb.CrosstoolRelease) (
	map[string][]string, map[string]map[string][]string, error) {
	featureNameToFeature := make(map[string]map[string][]string)
	toolchainToFeatures := make(map[string][]string)
	for _, toolchain := range crosstool.GetToolchain() {
		id := toolchain.GetToolchainIdentifier()
		if len(toolchain.GetFeature()) == 0 {
			toolchainToFeatures[id] = []string{}
		}
		for _, feature := range toolchain.GetFeature() {
			featureName := strings.ToLower(feature.GetName()) + "_feature"
			featureName = strings.Replace(featureName, "+", "p", -1)
			featureName = strings.Replace(featureName, ".", "_", -1)
			featureName = strings.Replace(featureName, "-", "_", -1)
			stringFeature, err := parseFeature(feature, 1)
			if err != nil {
				return nil, nil, fmt.Errorf(
					"Error in feature '%s': %v", feature.GetName(), err)
			}
			if _, ok := featureNameToFeature[featureName]; !ok {
				featureNameToFeature[featureName] = make(map[string][]string)
			}
			featureNameToFeature[featureName][stringFeature] = append(
				featureNameToFeature[featureName][stringFeature], id)
			toolchainToFeatures[id] = append(toolchainToFeatures[id], featureName)
		}
	}
	return toolchainToFeatures, featureNameToFeature, nil
}

func getFeaturesDeclaration(crosstool *crosstoolpb.CrosstoolRelease,
	cToolchainIdentifiers map[string]CToolchainIdentifier,
	featureNameToFeature map[string]map[string][]string, depth int) string {
	var res []string
	for featureName, featureStringToID := range featureNameToFeature {
		res = append(res,
			getAssignmentStatement(
				featureName,
				featureStringToID,
				crosstool,
				cToolchainIdentifiers,
				depth,
				/* isPlainString= */ false,
				/* shouldFail= */ false))
	}
	return strings.Join(res, "")
}

func getFeaturesStmt(cToolchainIdentifiers map[string]CToolchainIdentifier,
	toolchainToFeatures map[string][]string, depth int) string {
	var res []string
	arrToIdentifier := make(map[string][]string)
	for id, features := range toolchainToFeatures {
		arrayString := strings.Join(features, "{arrayFieldDelimiter}")
		arrToIdentifier[arrayString] = append(arrToIdentifier[arrayString], id)
	}
	res = append(res,
		getStringArrStatement(
			"features",
			arrToIdentifier,
			cToolchainIdentifiers,
			depth,
			/* isPlainString= */ false))
	return strings.Join(res, "\n")
}

func getActions(crosstool *crosstoolpb.CrosstoolRelease) (
	map[string][]string, map[string]map[string][]string, error) {
	actionNameToAction := make(map[string]map[string][]string)
	toolchainToActions := make(map[string][]string)
	for _, toolchain := range crosstool.GetToolchain() {
		id := toolchain.GetToolchainIdentifier()
		var actionName string
		if len(toolchain.GetActionConfig()) == 0 {
			toolchainToActions[id] = []string{}
		}
		for _, action := range toolchain.GetActionConfig() {
			if aName, ok := actionNames[action.GetActionName()]; ok {
				actionName = aName
			} else {
				actionName = strings.ToLower(action.GetActionName())
				actionName = strings.Replace(actionName, "+", "p", -1)
				actionName = strings.Replace(actionName, ".", "_", -1)
				actionName = strings.Replace(actionName, "-", "_", -1)
			}
			stringAction, err := parseAction(action, 1)
			if err != nil {
				return nil, nil, fmt.Errorf(
					"Error in action_config '%s': %v", action.GetActionName(), err)
			}
			if _, ok := actionNameToAction[actionName]; !ok {
				actionNameToAction[actionName] = make(map[string][]string)
			}
			actionNameToAction[actionName][stringAction] = append(
				actionNameToAction[actionName][stringAction], id)
			toolchainToActions[id] = append(
				toolchainToActions[id],
				strings.TrimPrefix(strings.ToLower(actionName), "action_names.")+"_action")
		}
	}
	return toolchainToActions, actionNameToAction, nil
}

func getActionConfigsDeclaration(
	crosstool *crosstoolpb.CrosstoolRelease,
	cToolchainIdentifiers map[string]CToolchainIdentifier,
	actionNameToAction map[string]map[string][]string, depth int) string {
	var res []string
	for actionName, actionStringToID := range actionNameToAction {
		variableName := strings.TrimPrefix(strings.ToLower(actionName), "action_names.") + "_action"
		res = append(res,
			getAssignmentStatement(
				variableName,
				actionStringToID,
				crosstool,
				cToolchainIdentifiers,
				depth,
				/* isPlainString= */ false,
				/* shouldFail= */ false))
	}
	return strings.Join(res, "")
}

func getActionConfigsStmt(
	cToolchainIdentifiers map[string]CToolchainIdentifier,
	toolchainToActions map[string][]string, depth int) string {
	var res []string
	arrToIdentifier := make(map[string][]string)
	for id, actions := range toolchainToActions {
		var arrayString string
		arrayString = strings.Join(actions, "{arrayFieldDelimiter}")
		arrToIdentifier[arrayString] = append(arrToIdentifier[arrayString], id)
	}
	res = append(res,
		getStringArrStatement(
			"action_configs",
			arrToIdentifier,
			cToolchainIdentifiers,
			depth,
			/* isPlainString= */ false))
	return strings.Join(res, "\n")
}

func parseAction(action *crosstoolpb.CToolchain_ActionConfig, depth int) (string, error) {
	actionName := action.GetActionName()
	aName := ""
	if val, ok := actionNames[actionName]; ok {
		aName = val
	} else {
		aName = "\"" + action.GetActionName() + "\""
	}
	name := fmt.Sprintf("action_name = %s", aName)
	fields := []string{name}
	if action.GetEnabled() {
		fields = append(fields, "enabled = True")
	}
	if len(action.GetFlagSet()) != 0 {
		flagSets, err := parseFlagSets(action.GetFlagSet(), depth+1)
		if err != nil {
			return "", err
		}
		fields = append(fields, "flag_sets = "+flagSets)
	}
	if len(action.GetImplies()) != 0 {
		implies := "implies = " +
			makeStringArr(action.GetImplies(), depth+1 /* isPlainString= */, true)
		fields = append(fields, implies)
	}
	if len(action.GetTool()) != 0 {
		tools := "tools = " + parseTools(action.GetTool(), depth+1)
		fields = append(fields, tools)
	}
	return createObject("action_config", fields, depth), nil
}

func getStringArrStatement(attr string, arrValToIds map[string][]string,
	cToolchainIdentifiers map[string]CToolchainIdentifier, depth int, plainString bool) string {
	var b bytes.Buffer
	if len(arrValToIds) == 0 {
		b.WriteString(fmt.Sprintf("%s%s = []\n", getTabs(depth), attr))
	} else if len(arrValToIds) == 1 {
		for value := range arrValToIds {
			var arr []string
			if value == "" {
				arr = []string{}
			} else if value == "None" {
				b.WriteString(fmt.Sprintf("%s%s = None\n", getTabs(depth), attr))
				break
			} else {
				arr = strings.Split(value, "{arrayFieldDelimiter}")
			}
			b.WriteString(
				fmt.Sprintf(
					"%s%s = %s\n",
					getTabs(depth),
					attr,
					makeStringArr(arr, depth+1, plainString)))
			break
		}
	} else {
		first := true
		var keys []string
		for k := range arrValToIds {
			keys = append(keys, k)
		}
		sort.Strings(keys)
		for _, value := range keys {
			ids := arrValToIds[value]
			branch := "elif"
			if first {
				branch = "if"
			}
			first = false
			var arr []string
			if value == "" {
				arr = []string{}
			} else if value == "None" {
				b.WriteString(
					getIfStatement(
						branch, ids, attr, "None", cToolchainIdentifiers,
						depth /* isPlainString= */, true))
				continue
			} else {
				arr = strings.Split(value, "{arrayFieldDelimiter}")
			}
			b.WriteString(
				getIfStatement(branch, ids, attr,
					makeStringArr(arr, depth+1, plainString),
					cToolchainIdentifiers, depth /* isPlainString= */, false))
		}
		b.WriteString(fmt.Sprintf("%selse:\n%sfail(\"Unreachable\")\n", getTabs(depth), getTabs(depth+1)))
	}
	b.WriteString("\n")
	return b.String()
}

func getStringArr(crosstool *crosstoolpb.CrosstoolRelease,
	cToolchainIdentifiers map[string]CToolchainIdentifier, attr string, depth int) string {
	var res []string
	arrToIdentifier := make(map[string][]string)
	for _, toolchain := range crosstool.GetToolchain() {
		id := toolchain.GetToolchainIdentifier()
		arrayString := strings.Join(getArrField(attr, toolchain), "{arrayFieldDelimiter}")
		arrToIdentifier[arrayString] = append(arrToIdentifier[arrayString], id)
	}
	statement := getStringArrStatement(attr, arrToIdentifier, cToolchainIdentifiers, depth /* isPlainString= */, true)
	res = append(res, statement)
	return strings.Join(res, "\n")
}

func getArrField(attr string, toolchain *crosstoolpb.CToolchain) []string {
	var arr []string
	if attr == "cxx_builtin_include_directories" {
		arr = toolchain.GetCxxBuiltinIncludeDirectory()
	}
	return arr
}

func getTabs(depth int) string {
	var res string
	for i := 0; i < depth; i++ {
		res = res + "    "
	}
	return res
}

func createObject(objtype string, fields []string, depth int) string {
	if len(fields) == 0 {
		return objtype + "()"
	}
	singleLine := objtype + "(" + strings.Join(fields, ", ") + ")"
	if len(singleLine) < 60 {
		return singleLine
	}
	return objtype +
		"(\n" +
		getTabs(depth+1) +
		strings.Join(fields, ",\n"+getTabs(depth+1)) +
		",\n" + getTabs(depth) +
		")"
}

func getArtifactNamePatterns(crosstool *crosstoolpb.CrosstoolRelease,
	cToolchainIdentifiers map[string]CToolchainIdentifier, depth int) string {
	var res []string
	artifactToIds := make(map[string][]string)
	for _, toolchain := range crosstool.GetToolchain() {
		artifactNamePatterns := parseArtifactNamePatterns(
			toolchain.GetArtifactNamePattern(),
			depth)
		artifactToIds[artifactNamePatterns] = append(
			artifactToIds[artifactNamePatterns],
			toolchain.GetToolchainIdentifier())
	}
	res = append(res,
		getAssignmentStatement(
			"artifact_name_patterns",
			artifactToIds,
			crosstool,
			cToolchainIdentifiers,
			depth,
			/* isPlainString= */ false,
			/* shouldFail= */ true))
	return strings.Join(res, "\n")
}

func parseArtifactNamePatterns(
	artifactNamePatterns []*crosstoolpb.CToolchain_ArtifactNamePattern, depth int) string {
	var res []string
	for _, pattern := range artifactNamePatterns {
		res = append(res, parseArtifactNamePattern(pattern, depth+1))
	}
	return makeStringArr(res, depth /* isPlainString= */, false)
}

func parseArtifactNamePattern(
	artifactNamePattern *crosstoolpb.CToolchain_ArtifactNamePattern, depth int) string {
	categoryName := fmt.Sprintf("category_name = \"%s\"", artifactNamePattern.GetCategoryName())
	prefix := fmt.Sprintf("prefix = \"%s\"", artifactNamePattern.GetPrefix())
	extension := fmt.Sprintf("extension = \"%s\"", artifactNamePattern.GetExtension())
	fields := []string{categoryName, prefix, extension}
	return createObject("artifact_name_pattern", fields, depth)
}

func parseFeature(feature *crosstoolpb.CToolchain_Feature, depth int) (string, error) {
	name := fmt.Sprintf("name = \"%s\"", feature.GetName())

	fields := []string{name}
	if feature.GetEnabled() {
		fields = append(fields, "enabled = True")
	}

	if len(feature.GetFlagSet()) > 0 {
		flagSets, err := parseFlagSets(feature.GetFlagSet(), depth+1)
		if err != nil {
			return "", err
		}
		fields = append(fields, "flag_sets = "+flagSets)
	}
	if len(feature.GetEnvSet()) > 0 {
		envSets := "env_sets = " + parseEnvSets(feature.GetEnvSet(), depth+1)
		fields = append(fields, envSets)
	}
	if len(feature.GetRequires()) > 0 {
		requires := "requires = " + parseFeatureSets(feature.GetRequires(), depth+1)
		fields = append(fields, requires)
	}
	if len(feature.GetImplies()) > 0 {
		implies := "implies = " +
			makeStringArr(feature.GetImplies(), depth+1 /* isPlainString= */, true)
		fields = append(fields, implies)
	}
	if len(feature.GetProvides()) > 0 {
		provides := "provides = " +
			makeStringArr(feature.GetProvides(), depth+1 /* isPlainString= */, true)
		fields = append(fields, provides)
	}
	return createObject("feature", fields, depth), nil
}

func parseFlagSets(flagSets []*crosstoolpb.CToolchain_FlagSet, depth int) (string, error) {
	var res []string
	for _, flagSet := range flagSets {
		parsedFlagset, err := parseFlagSet(flagSet, depth+1)
		if err != nil {
			return "", err
		}
		res = append(res, parsedFlagset)
	}
	return makeStringArr(res, depth /* isPlainString= */, false), nil
}

func parseFlagSet(flagSet *crosstoolpb.CToolchain_FlagSet, depth int) (string, error) {
	var fields []string
	if len(flagSet.GetAction()) > 0 {
		actionArr := processActions(flagSet.GetAction(), depth)
		actions := "actions = " + strings.Join(actionArr, " +\n"+getTabs(depth+2))
		fields = append(fields, actions)
	}
	if len(flagSet.GetFlagGroup()) > 0 {
		flagGroups, err := parseFlagGroups(flagSet.GetFlagGroup(), depth+1)
		if err != nil {
			return "", err
		}
		fields = append(fields, "flag_groups = "+flagGroups)
	}
	if len(flagSet.GetWithFeature()) > 0 {
		withFeatures := "with_features = " +
			parseWithFeatureSets(flagSet.GetWithFeature(), depth+1)
		fields = append(fields, withFeatures)
	}
	return createObject("flag_set", fields, depth), nil
}

func parseFlagGroups(flagGroups []*crosstoolpb.CToolchain_FlagGroup, depth int) (string, error) {
	var res []string
	for _, flagGroup := range flagGroups {
		flagGroupString, err := parseFlagGroup(flagGroup, depth+1)
		if err != nil {
			return "", err
		}
		res = append(res, flagGroupString)
	}
	return makeStringArr(res, depth /* isPlainString= */, false), nil
}

func parseFlagGroup(flagGroup *crosstoolpb.CToolchain_FlagGroup, depth int) (string, error) {
	var res []string
	if len(flagGroup.GetFlag()) != 0 {
		res = append(res, "flags = "+makeStringArr(flagGroup.GetFlag(), depth+1, true))
	}
	if flagGroup.GetIterateOver() != "" {
		res = append(res, fmt.Sprintf("iterate_over = \"%s\"", flagGroup.GetIterateOver()))
	}
	if len(flagGroup.GetFlagGroup()) != 0 {
		flagGroupString, err := parseFlagGroups(flagGroup.GetFlagGroup(), depth+1)
		if err != nil {
			return "", err
		}
		res = append(res, "flag_groups = "+flagGroupString)
	}
	if len(flagGroup.GetExpandIfAllAvailable()) > 1 {
		return "", errors.New("Flag group must not have more than one 'expand_if_all_available' field")
	}
	if len(flagGroup.GetExpandIfAllAvailable()) != 0 {
		res = append(res,
			fmt.Sprintf(
				"expand_if_available = \"%s\"",
				flagGroup.GetExpandIfAllAvailable()[0]))
	}
	if len(flagGroup.GetExpandIfNoneAvailable()) > 1 {
		return "", errors.New("Flag group must not have more than one 'expand_if_none_available' field")
	}
	if len(flagGroup.GetExpandIfNoneAvailable()) != 0 {
		res = append(res,
			fmt.Sprintf(
				"expand_if_not_available = \"%s\"",
				flagGroup.GetExpandIfNoneAvailable()[0]))
	}
	if flagGroup.GetExpandIfTrue() != "" {
		res = append(res, fmt.Sprintf("expand_if_true = \"%s\"",
			flagGroup.GetExpandIfTrue()))
	}
	if flagGroup.GetExpandIfFalse() != "" {
		res = append(res, fmt.Sprintf("expand_if_false = \"%s\"",
			flagGroup.GetExpandIfFalse()))
	}
	if flagGroup.GetExpandIfEqual() != nil {
		res = append(res,
			"expand_if_equal = "+parseVariableWithValue(
				flagGroup.GetExpandIfEqual(), depth+1))
	}
	return createObject("flag_group", res, depth), nil
}

func parseVariableWithValue(variable *crosstoolpb.CToolchain_VariableWithValue, depth int) string {
	variableName := fmt.Sprintf("name = \"%s\"", variable.GetVariable())
	value := fmt.Sprintf("value = \"%s\"", variable.GetValue())
	return createObject("variable_with_value", []string{variableName, value}, depth)
}

func getToolPaths(crosstool *crosstoolpb.CrosstoolRelease,
	cToolchainIdentifiers map[string]CToolchainIdentifier, depth int) string {
	var res []string
	toolPathsToIds := make(map[string][]string)
	for _, toolchain := range crosstool.GetToolchain() {
		toolPaths := parseToolPaths(toolchain.GetToolPath(), depth)
		toolPathsToIds[toolPaths] = append(
			toolPathsToIds[toolPaths],
			toolchain.GetToolchainIdentifier())
	}
	res = append(res,
		getAssignmentStatement(
			"tool_paths",
			toolPathsToIds,
			crosstool,
			cToolchainIdentifiers,
			depth,
			/* isPlainString= */ false,
			/* shouldFail= */ true))
	return strings.Join(res, "\n")
}

func parseToolPaths(toolPaths []*crosstoolpb.ToolPath, depth int) string {
	var res []string
	for _, toolPath := range toolPaths {
		res = append(res, parseToolPath(toolPath, depth+1))
	}
	return makeStringArr(res, depth /* isPlainString= */, false)
}

func parseToolPath(toolPath *crosstoolpb.ToolPath, depth int) string {
	name := fmt.Sprintf("name = \"%s\"", toolPath.GetName())
	path := toolPath.GetPath()
	if path == "" {
		path = "NOT_USED"
	}
	path = fmt.Sprintf("path = \"%s\"", path)
	return createObject("tool_path", []string{name, path}, depth)
}

func getMakeVariables(crosstool *crosstoolpb.CrosstoolRelease,
	cToolchainIdentifiers map[string]CToolchainIdentifier, depth int) string {
	var res []string
	makeVariablesToIds := make(map[string][]string)
	for _, toolchain := range crosstool.GetToolchain() {
		makeVariables := parseMakeVariables(toolchain.GetMakeVariable(), depth)
		makeVariablesToIds[makeVariables] = append(
			makeVariablesToIds[makeVariables],
			toolchain.GetToolchainIdentifier())
	}
	res = append(res,
		getAssignmentStatement(
			"make_variables",
			makeVariablesToIds,
			crosstool,
			cToolchainIdentifiers,
			depth,
			/* isPlainString= */ false,
			/* shouldFail= */ true))
	return strings.Join(res, "\n")
}

func parseMakeVariables(makeVariables []*crosstoolpb.MakeVariable, depth int) string {
	var res []string
	for _, makeVariable := range makeVariables {
		res = append(res, parseMakeVariable(makeVariable, depth+1))
	}
	return makeStringArr(res, depth /* isPlainString= */, false)
}

func parseMakeVariable(makeVariable *crosstoolpb.MakeVariable, depth int) string {
	name := fmt.Sprintf("name = \"%s\"", makeVariable.GetName())
	value := fmt.Sprintf("value = \"%s\"", makeVariable.GetValue())
	return createObject("make_variable", []string{name, value}, depth)
}

func parseTools(tools []*crosstoolpb.CToolchain_Tool, depth int) string {
	var res []string
	for _, tool := range tools {
		res = append(res, parseTool(tool, depth+1))
	}
	return makeStringArr(res, depth /* isPlainString= */, false)
}

func parseTool(tool *crosstoolpb.CToolchain_Tool, depth int) string {
	toolPath := "path = \"NOT_USED\""
	if tool.GetToolPath() != "" {
		toolPath = fmt.Sprintf("path = \"%s\"", tool.GetToolPath())
	}
	fields := []string{toolPath}
	if len(tool.GetWithFeature()) != 0 {
		withFeatures := "with_features = " + parseWithFeatureSets(tool.GetWithFeature(), depth+1)
		fields = append(fields, withFeatures)
	}
	if len(tool.GetExecutionRequirement()) != 0 {
		executionRequirements := "execution_requirements = " +
			makeStringArr(tool.GetExecutionRequirement(), depth+1 /* isPlainString= */, true)
		fields = append(fields, executionRequirements)
	}
	return createObject("tool", fields, depth)
}

func parseEnvEntries(envEntries []*crosstoolpb.CToolchain_EnvEntry, depth int) string {
	var res []string
	for _, envEntry := range envEntries {
		res = append(res, parseEnvEntry(envEntry, depth+1))
	}
	return makeStringArr(res, depth /* isPlainString= */, false)
}

func parseEnvEntry(envEntry *crosstoolpb.CToolchain_EnvEntry, depth int) string {
	key := fmt.Sprintf("key = \"%s\"", envEntry.GetKey())
	value := fmt.Sprintf("value = \"%s\"", envEntry.GetValue())
	return createObject("env_entry", []string{key, value}, depth)
}

func parseWithFeatureSets(withFeatureSets []*crosstoolpb.CToolchain_WithFeatureSet,
	depth int) string {
	var res []string
	for _, withFeature := range withFeatureSets {
		res = append(res, parseWithFeatureSet(withFeature, depth+1))
	}
	return makeStringArr(res, depth /* isPlainString= */, false)
}

func parseWithFeatureSet(withFeature *crosstoolpb.CToolchain_WithFeatureSet,
	depth int) string {
	var fields []string
	if len(withFeature.GetFeature()) != 0 {
		features := "features = " +
			makeStringArr(withFeature.GetFeature(), depth+1 /* isPlainString= */, true)
		fields = append(fields, features)
	}
	if len(withFeature.GetNotFeature()) != 0 {
		notFeatures := "not_features = " +
			makeStringArr(withFeature.GetNotFeature(), depth+1 /* isPlainString= */, true)
		fields = append(fields, notFeatures)
	}
	return createObject("with_feature_set", fields, depth)
}

func parseEnvSets(envSets []*crosstoolpb.CToolchain_EnvSet, depth int) string {
	var res []string
	for _, envSet := range envSets {
		envSetString := parseEnvSet(envSet, depth+1)
		res = append(res, envSetString)
	}
	return makeStringArr(res, depth /* isPlainString= */, false)
}

func parseEnvSet(envSet *crosstoolpb.CToolchain_EnvSet, depth int) string {
	actionsStatement := processActions(envSet.GetAction(), depth)
	actions := "actions = " + strings.Join(actionsStatement, " +\n"+getTabs(depth+2))
	fields := []string{actions}
	if len(envSet.GetEnvEntry()) != 0 {
		envEntries := "env_entries = " + parseEnvEntries(envSet.GetEnvEntry(), depth+1)
		fields = append(fields, envEntries)
	}
	if len(envSet.GetWithFeature()) != 0 {
		withFeatures := "with_features = " + parseWithFeatureSets(envSet.GetWithFeature(), depth+1)
		fields = append(fields, withFeatures)
	}
	return createObject("env_set", fields, depth)
}

func parseFeatureSets(featureSets []*crosstoolpb.CToolchain_FeatureSet, depth int) string {
	var res []string
	for _, featureSet := range featureSets {
		res = append(res, parseFeatureSet(featureSet, depth+1))
	}
	return makeStringArr(res, depth /* isPlainString= */, false)
}

func parseFeatureSet(featureSet *crosstoolpb.CToolchain_FeatureSet, depth int) string {
	features := "features = " +
		makeStringArr(featureSet.GetFeature(), depth+1 /* isPlainString= */, true)
	return createObject("feature_set", []string{features}, depth)
}

// Takes in a list of string elements and returns a string that represents
// an array :
//     [
//         "element1",
//         "element2",
//     ]
// The isPlainString argument tells us whether the input elements should be
// treated as string (eg, flags), or not (eg, variable names)
func makeStringArr(arr []string, depth int, isPlainString bool) string {
	if len(arr) == 0 {
		return "[]"
	}
	var escapedArr []string
	for _, el := range arr {
		if isPlainString {
			escapedArr = append(escapedArr, strings.Replace(el, "\"", "\\\"", -1))
		} else {
			escapedArr = append(escapedArr, el)
		}
	}
	addQuote := ""
	if isPlainString {
		addQuote = "\""
	}
	singleLine := "[" + addQuote + strings.Join(escapedArr, addQuote+", "+addQuote) + addQuote + "]"
	if len(singleLine) < 60 {
		return singleLine
	}
	return "[\n" +
		getTabs(depth+1) +
		addQuote +
		strings.Join(escapedArr, addQuote+",\n"+getTabs(depth+1)+addQuote) +
		addQuote +
		",\n" +
		getTabs(depth) +
		"]"
}

// Returns a string that represents a value assignment
// (eg if ctx.attr.cpu == "linux":
//         compiler = "llvm"
//     elif ctx.attr.cpu == "windows":
//         compiler = "mingw"
//     else:
//         fail("Unreachable")
func getAssignmentStatement(field string, valToIds map[string][]string,
	crosstool *crosstoolpb.CrosstoolRelease,
	toCToolchainIdentifier map[string]CToolchainIdentifier,
	depth int, isPlainString, shouldFail bool) string {
	var b bytes.Buffer
	if len(valToIds) <= 1 {
		// if there is only one possible value for this field, we don't need if statements
		for val := range valToIds {
			if val != "None" && isPlainString {
				val = "\"" + val + "\""
			}
			b.WriteString(fmt.Sprintf("%s%s = %s\n", getTabs(depth), field, val))
			break
		}
	} else {
		first := true
		var keys []string
		for k := range valToIds {
			keys = append(keys, k)
		}
		sort.Strings(keys)
		for _, value := range keys {
			ids := valToIds[value]
			branch := "elif"
			if first {
				branch = "if"
			}
			b.WriteString(
				getIfStatement(branch, ids, field, value,
					toCToolchainIdentifier, depth, isPlainString))
			first = false
		}
		if shouldFail {
			b.WriteString(
				fmt.Sprintf(
					"%selse:\n%sfail(\"Unreachable\")\n",
					getTabs(depth), getTabs(depth+1)))
		}
	}
	b.WriteString("\n")
	return b.String()
}

func getCPUToCompilers(identifiers []CToolchainIdentifier) map[string][]string {
	res := make(map[string][]string)
	for _, identifier := range identifiers {
		if identifier.compiler != "" {
			res[identifier.cpu] = append(res[identifier.cpu], identifier.compiler)
		}
	}
	return res
}

func getIfStatement(ifOrElseIf string, identifiers []string, field, val string,
	toCToolchainIdentifier map[string]CToolchainIdentifier, depth int,
	isPlainString bool) string {
	usedStmts := make(map[string]bool)
	if val != "None" && isPlainString {
		val = "\"" + val + "\""
	}
	var cToolchainIdentifiers []CToolchainIdentifier
	for _, value := range toCToolchainIdentifier {
		cToolchainIdentifiers = append(cToolchainIdentifiers, value)
	}
	cpuToCompilers := getCPUToCompilers(cToolchainIdentifiers)
	countCpus := make(map[string]int)
	var conditions []string
	for _, id := range identifiers {
		identifier := toCToolchainIdentifier[id]
		stmt := getConditionStatementForCToolchainIdentifier(identifier)
		if _, ok := usedStmts[stmt]; !ok {
			conditions = append(conditions, stmt)
			usedStmts[stmt] = true
			if identifier.compiler != "" {
				countCpus[identifier.cpu]++
			}
		}
	}

	var compressedConditions []string
	usedStmtsOptimized := make(map[string]bool)
	for _, id := range identifiers {
		identifier := toCToolchainIdentifier[id]
		var stmt string
		if _, ok := countCpus[identifier.cpu]; ok {
			if countCpus[identifier.cpu] == len(cpuToCompilers[identifier.cpu]) {
				stmt = getConditionStatementForCToolchainIdentifier(
					CToolchainIdentifier{cpu: identifier.cpu, compiler: ""})
			} else {
				stmt = getConditionStatementForCToolchainIdentifier(identifier)
			}
		} else {
			stmt = getConditionStatementForCToolchainIdentifier(identifier)
		}
		if _, ok := usedStmtsOptimized[stmt]; !ok {
			compressedConditions = append(compressedConditions, stmt)
			usedStmtsOptimized[stmt] = true
		}
	}

	sort.Strings(compressedConditions)
	val = strings.Join(strings.Split(val, "\n"+getTabs(depth)), "\n"+getTabs(depth+1))
	return fmt.Sprintf(`%s%s %s:
%s%s = %s
`, getTabs(depth),
		ifOrElseIf,
		"("+strings.Join(compressedConditions, "\n"+getTabs(depth+1)+"or ")+")",
		getTabs(depth+1),
		field,
		val)
}

func getToolchainIdentifiers(crosstool *crosstoolpb.CrosstoolRelease) []string {
	var res []string
	for _, toolchain := range crosstool.GetToolchain() {
		res = append(res, toolchain.GetToolchainIdentifier())
	}
	return res
}

func getHostSystemNames(crosstool *crosstoolpb.CrosstoolRelease) []string {
	var res []string
	for _, toolchain := range crosstool.GetToolchain() {
		res = append(res, toolchain.GetHostSystemName())
	}
	return res
}

func getTargetSystemNames(crosstool *crosstoolpb.CrosstoolRelease) []string {
	var res []string
	for _, toolchain := range crosstool.GetToolchain() {
		res = append(res, toolchain.GetTargetSystemName())
	}
	return res
}

func getTargetCpus(crosstool *crosstoolpb.CrosstoolRelease) []string {
	var res []string
	for _, toolchain := range crosstool.GetToolchain() {
		res = append(res, toolchain.GetTargetCpu())
	}
	return res
}

func getTargetLibcs(crosstool *crosstoolpb.CrosstoolRelease) []string {
	var res []string
	for _, toolchain := range crosstool.GetToolchain() {
		res = append(res, toolchain.GetTargetLibc())
	}
	return res
}

func getCompilers(crosstool *crosstoolpb.CrosstoolRelease) []string {
	var res []string
	for _, toolchain := range crosstool.GetToolchain() {
		res = append(res, toolchain.GetCompiler())
	}
	return res
}

func getAbiVersions(crosstool *crosstoolpb.CrosstoolRelease) []string {
	var res []string
	for _, toolchain := range crosstool.GetToolchain() {
		res = append(res, toolchain.GetAbiVersion())
	}
	return res
}

func getAbiLibcVersions(crosstool *crosstoolpb.CrosstoolRelease) []string {
	var res []string
	for _, toolchain := range crosstool.GetToolchain() {
		res = append(res, toolchain.GetAbiLibcVersion())
	}
	return res
}

func getCcTargetOss(crosstool *crosstoolpb.CrosstoolRelease) []string {
	var res []string
	for _, toolchain := range crosstool.GetToolchain() {
		targetOS := "None"
		if toolchain.GetCcTargetOs() != "" {
			targetOS = toolchain.GetCcTargetOs()
		}
		res = append(res, targetOS)
	}
	return res
}

func getBuiltinSysroots(crosstool *crosstoolpb.CrosstoolRelease) []string {
	var res []string
	for _, toolchain := range crosstool.GetToolchain() {
		sysroot := "None"
		if toolchain.GetBuiltinSysroot() != "" {
			sysroot = toolchain.GetBuiltinSysroot()
		}
		res = append(res, sysroot)
	}
	return res
}

func getMappedStringValuesToIdentifiers(identifiers, fields []string) map[string][]string {
	res := make(map[string][]string)
	for i := range identifiers {
		res[fields[i]] = append(res[fields[i]], identifiers[i])
	}
	return res
}

func getReturnStatement() string {
	return `
    out = ctx.actions.declare_file(ctx.label.name)
    ctx.actions.write(out, "Fake executable")
    return [
        cc_common.create_cc_toolchain_config_info(
            ctx = ctx,
            features = features,
            action_configs = action_configs,
            artifact_name_patterns = artifact_name_patterns,
            cxx_builtin_include_directories = cxx_builtin_include_directories,
            toolchain_identifier = toolchain_identifier,
            host_system_name = host_system_name,
            target_system_name = target_system_name,
            target_cpu = target_cpu,
            target_libc = target_libc,
            compiler = compiler,
            abi_version = abi_version,
            abi_libc_version = abi_libc_version,
            tool_paths = tool_paths,
            make_variables = make_variables,
            builtin_sysroot = builtin_sysroot,
            cc_target_os = cc_target_os
        ),
        DefaultInfo(
            executable = out,
        ),
    ]
`
}

// Transform writes a cc_toolchain_config rule functionally equivalent to the
// CROSSTOOL file.
func Transform(crosstool *crosstoolpb.CrosstoolRelease) (string, error) {
	var b bytes.Buffer

	cToolchainIdentifiers := toolchainToCToolchainIdentifier(crosstool)

	toolchainToFeatures, featureNameToFeature, err := getFeatures(crosstool)
	if err != nil {
		return "", err
	}

	toolchainToActions, actionNameToAction, err := getActions(crosstool)
	if err != nil {
		return "", err
	}

	header := getCcToolchainConfigHeader()
	if _, err := b.WriteString(header); err != nil {
		return "", err
	}

	loadActionsStmt := getLoadActionsStmt()
	if _, err := b.WriteString(loadActionsStmt); err != nil {
		return "", err
	}

	implHeader := getImplHeader()
	if _, err := b.WriteString(implHeader); err != nil {
		return "", err
	}

	stringFields := []string{
		"toolchain_identifier",
		"host_system_name",
		"target_system_name",
		"target_cpu",
		"target_libc",
		"compiler",
		"abi_version",
		"abi_libc_version",
		"cc_target_os",
		"builtin_sysroot",
	}

	for _, stringField := range stringFields {
		stmt := getStringStatement(crosstool, cToolchainIdentifiers, stringField, 1)
		if _, err := b.WriteString(stmt); err != nil {
			return "", err
		}
	}

	listsOfActions := []string{
		"all_compile_actions",
		"all_cpp_compile_actions",
		"preprocessor_compile_actions",
		"codegen_compile_actions",
		"all_link_actions",
	}

	for _, listOfActions := range listsOfActions {
		actions := getListOfActions(listOfActions, 1)
		if _, err := b.WriteString(actions); err != nil {
			return "", err
		}
	}

	actionConfigDeclaration := getActionConfigsDeclaration(
		crosstool, cToolchainIdentifiers, actionNameToAction, 1)
	if _, err := b.WriteString(actionConfigDeclaration); err != nil {
		return "", err
	}

	actionConfigStatement := getActionConfigsStmt(
		cToolchainIdentifiers, toolchainToActions, 1)
	if _, err := b.WriteString(actionConfigStatement); err != nil {
		return "", err
	}

	featureDeclaration := getFeaturesDeclaration(
		crosstool, cToolchainIdentifiers, featureNameToFeature, 1)
	if _, err := b.WriteString(featureDeclaration); err != nil {
		return "", err
	}

	featuresStatement := getFeaturesStmt(
		cToolchainIdentifiers, toolchainToFeatures, 1)
	if _, err := b.WriteString(featuresStatement); err != nil {
		return "", err
	}

	includeDirectories := getStringArr(
		crosstool, cToolchainIdentifiers, "cxx_builtin_include_directories", 1)
	if _, err := b.WriteString(includeDirectories); err != nil {
		return "", err
	}

	artifactNamePatterns := getArtifactNamePatterns(
		crosstool, cToolchainIdentifiers, 1)
	if _, err := b.WriteString(artifactNamePatterns); err != nil {
		return "", err
	}

	makeVariables := getMakeVariables(crosstool, cToolchainIdentifiers, 1)
	if _, err := b.WriteString(makeVariables); err != nil {
		return "", err
	}

	toolPaths := getToolPaths(crosstool, cToolchainIdentifiers, 1)
	if _, err := b.WriteString(toolPaths); err != nil {
		return "", err
	}

	if _, err := b.WriteString(getReturnStatement()); err != nil {
		return "", err
	}

	rule := getRule(cToolchainIdentifiers)
	if _, err := b.WriteString(rule); err != nil {
		return "", err
	}

	return b.String(), nil
}
