/*
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"
	"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("@bazel_tools//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",
	"ld_embed_data":                   "ACTION_NAMES.ld_embed_data",
}

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)
}

func getFeatures(crosstool *crosstoolpb.CrosstoolRelease) (
	map[string][]string, map[string]map[string][]string) {
	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)
			stringFeature := parseFeature(feature, 1)
			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
}

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))
	}
	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) {
	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)
			}
			stringAction := parseAction(action, 1)
			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
}

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))
	}
	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 {
	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 := "flag_sets = " +
			parseFlagSets(action.GetFlagSet(), depth+1)
		fields = append(fields, 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)
}

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))
	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 {
	name := fmt.Sprintf("name = \"%s\"", feature.GetName())

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

	if len(feature.GetFlagSet()) > 0 {
		flagSets := "flag_sets = " +
			parseFlagSets(feature.GetFlagSet(), depth+1)
		fields = append(fields, 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)
}

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

func parseFlagSet(flagSet *crosstoolpb.CToolchain_FlagSet, depth int) string {
	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 := "flag_groups = " +
			parseFlagGroups(flagSet.GetFlagGroup(), depth+1)
		fields = append(fields, flagGroups)
	}
	if len(flagSet.GetWithFeature()) > 0 {
		withFeatures := "with_features = " +
			parseWithFeatureSets(flagSet.GetWithFeature(), depth+1)
		fields = append(fields, withFeatures)
	}
	return createObject("flag_set", fields, depth)
}

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

func parseFlagGroup(flagGroup *crosstoolpb.CToolchain_FlagGroup, depth int) string {
	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 {
		res = append(res, "flag_groups = "+parseFlagGroups(flagGroup.GetFlagGroup(), depth+1))
	}
	if len(flagGroup.GetExpandIfAllAvailable()) != 0 {
		res = append(res,
			fmt.Sprintf(
				"expand_if_available = \"%s\"",
				flagGroup.GetExpandIfAllAvailable()[0]))
	}
	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)
}

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))
	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))
	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 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
		}
		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 := getFeatures(crosstool)

	toolchainToActions, actionNameToAction := getActions(crosstool)

	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
}
