// Package template contains the logic for parsing templates.
package template

import (
	"strings"
)

// TemplateType represents whether a template is short, long, or invalid.
type TemplateType int

const (
	InvalidTemplate TemplateType = iota
	ShortTemplate
	ExtendedTemplate
)

// DetectTemplateType checks if the template is short or long.
func DetectTemplateType(tmpl Slice) TemplateType {
	trimmed := strings.TrimSpace(tmpl.String())

	// Short type: starts with "{" and ends with "}" on a single line,
	// and contains "|" or "," inside for inline definition
	// Matchs for example { name | text,required }
	if strings.HasPrefix(trimmed, "{") &&
		strings.HasSuffix(trimmed, "}") &&
		!strings.Contains(trimmed, "\n") {
		return ShortTemplate
	}

	// Long type: multiline and contains keys like "path:" or "codec:" inside
	// Matches for example:
	// {
	//   path: name
	//   codec: text
	//   required: true
	// }
	if strings.Contains(trimmed, "\n") &&
		(strings.Contains(trimmed, "path:") || strings.Contains(trimmed, "codec:")) {
		return ExtendedTemplate
	}

	return InvalidTemplate
}

func cleanTemplate(input Slice) string {
	s := strings.TrimSpace(input.String())
	s = strings.TrimPrefix(s, "{")
	s = strings.TrimSuffix(s, "}")
	s = strings.Trim(s, "\n")
	return s
}

func ParseTemplateBlock(template Slice, blockType BlockType) (block Block, err error) {
	if blockType == MatchingBlock {
		return Block{
			Type:    MatchingBlock,
			content: template,
		}, nil
	}

	switch DetectTemplateType(template) {
	case ShortTemplate:
		return parseShortTemplate(template)
	case ExtendedTemplate:
		return parseYamlTemplate(template)
	}

	return block, NewErrorf("invalid template: '%s'", template.String()).WithPosition(template.start, template.end)
}
