// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package bazel_docgen

import (
	"strings"
	"text/template"

	pb "go.fuchsia.dev/fuchsia/tools/bazel-docgen/third_party/stardoc"
)

const ruleTemplate = `
[TOC]

# {{ .RuleName }}

{{ .DocString }}

## **ATTRIBUTES**

| Name  | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
{{range .Attribute }}| {{ .Name }} | {{description .DocString }} | {{attributeTypeString .Type }} | {{isMandatory .Mandatory }} | {{defaultValue .DefaultValue }} |
{{end }}
`

const providerTemplate = `
[TOC]

# {{ .ProviderName }}

{{ .DocString }}

{{if .FieldInfo }}## **FIELDS**


| Name  | Description |
| :------------- | :------------- |
{{range .FieldInfo }}| {{ .Name }} | {{description .DocString }} |
{{end}}{{end}}
`

const starlarkFunctionTemplate = `
[TOC]

# {{ .FunctionName }}

{{ .DocString }}

{{if .Parameter }}## **PARAMETERS**


| Name  | Description | Default |
| :------------- | :------------- | :------------- |
{{range .Parameter }}| {{ .Name }} | {{description .DocString }} | {{defaultValue .DefaultValue }} |
{{end}}{{end}}

{{if .Return }}
**RETURNS**

{{with .Return }}{{ .DocString }}{{end}}
{{end}}
`

const repositoryRuleTemplate = `
[TOC]

# {{ .RuleName }}

{{ .DocString }}

## **ATTRIBUTES**

| Name  | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
{{range .Attribute }}| {{ .Name }} | {{description .DocString }} | {{attributeTypeString .Type }} | {{isMandatory .Mandatory }} | {{defaultValue .DefaultValue }} |
{{end }}

{{if .Environ}}
## **ENVIRONMENT VARIABLES**

This repository rule depends on the following environment variables:

{{range .Environ}}* {{codeBlock .}}{{end}}
{{end}}
`

var (
	attributeTypeURLMap = map[pb.AttributeType]string{
		pb.AttributeType_INT:               "int",
		pb.AttributeType_LABEL:             "label",
		pb.AttributeType_STRING:            "string",
		pb.AttributeType_STRING_LIST:       "string_list",
		pb.AttributeType_INT_LIST:          "int_list",
		pb.AttributeType_LABEL_LIST:        "label_list",
		pb.AttributeType_BOOLEAN:           "bool",
		pb.AttributeType_LABEL_STRING_DICT: "label_keyed_string_dict",
		pb.AttributeType_STRING_DICT:       "string_dict",
		pb.AttributeType_STRING_LIST_DICT:  "string_list_dict",
		pb.AttributeType_OUTPUT:            "output",
		pb.AttributeType_OUTPUT_LIST:       "output_list",
	}
	attributeTypeReadableNameMap = map[pb.AttributeType]string{
		pb.AttributeType_INT:               "Integer",
		pb.AttributeType_LABEL:             "Label",
		pb.AttributeType_STRING:            "String",
		pb.AttributeType_STRING_LIST:       "String List",
		pb.AttributeType_INT_LIST:          "Integer List",
		pb.AttributeType_LABEL_LIST:        "Label List",
		pb.AttributeType_BOOLEAN:           "Boolean",
		pb.AttributeType_LABEL_STRING_DICT: "Label String Dict",
		pb.AttributeType_STRING_DICT:       "String Dict",
		pb.AttributeType_STRING_LIST_DICT:  "String List Dict",
		pb.AttributeType_OUTPUT:            "Output",
		pb.AttributeType_OUTPUT_LIST:       "Output List",
	}
)

func defaultValue(value string) string {
	if value == "" {
		return "-"
	}
	// Return the value with backticks if there is one
	return "`" + value + "`"
}

func codeBlock(value string) string {
	return "`" + value + "`"
}

type stringReplacements struct {
	input       string
	replacement string
}

// Makes the description renderable inside of a markdown table.
// TODO: properly support code blocks.
func description(value string) string {
	if value == "" {
		return "-"
	}

	// Replace the values of the description that would cause problems rendering
	// in a table context.
	replacements := []stringReplacements{
		{"<", "&lt;"},
		{">", "&gt;"},
		{"|", "\\|"},
		{"\n", "<br>"},
	}
	value = strings.TrimSpace(value)
	for _, r := range replacements {
		value = strings.ReplaceAll(value, r.input, r.replacement)
	}
	return value
}

func attributeTypeString(t pb.AttributeType) string {
	if t == pb.AttributeType_NAME {
		return "<a href=\"https://bazel.build/concepts/labels#target-names\">Name</a>"
	} else if t == pb.AttributeType_UNKNOWN {
		return "UKNOWN"
	} else {
		return "<a href=\"https://bazel.build/rules/lib/toplevel/attr#" + attributeTypeURLMap[t] + "\">" + attributeTypeReadableNameMap[t] + "</a>"
	}
}

func isMandatory(m bool) string {
	if m {
		return "required"
	} else {
		return "optional"
	}
}
func NewRuleTemplate() (*template.Template, error) {
	return makeTemplate("rule", ruleTemplate)
}

func NewProviderTemplate() (*template.Template, error) {
	return makeTemplate("provider", providerTemplate)
}

func NewStarlarkFunctionTemplate() (*template.Template, error) {
	return makeTemplate("starlark_function", starlarkFunctionTemplate)
}

func NewRepositoryRuleTemplate() (*template.Template, error) {
	return makeTemplate("repository_rule", repositoryRuleTemplate)
}

func makeTemplate(name string, templateString string) (*template.Template, error) {
	t := template.New(name)
	t.Funcs(
		template.FuncMap{
			"defaultValue":        defaultValue,
			"description":         description,
			"attributeTypeString": attributeTypeString,
			"isMandatory":         isMandatory,
			"codeBlock":           codeBlock,
		},
	)
	return t.Parse(templateString)
}
