/*
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(
    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)))
		} else {
			b.WriteString(
				fmt.Sprintf(
					"%selse:\n%s%s = None\n",
					getTabs(depth), getTabs(depth+1), field))
		}
	}
	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
}
