// Package sherpadoc contains types for reading and writing documentation for sherpa API's.
package sherpadoc

const (
	// SherpadocVersion is the sherpadoc version generated by this command.
	SherpadocVersion = 1
)

// Section represents documentation about a Sherpa API section, as returned by the "_docs" function.
type Section struct {
	Name      string      // Name of an API section.
	Docs      string      // Explanation of the API in text or markdown.
	Functions []*Function // Functions in this section.
	Sections  []*Section  // Subsections, each with their own documentation.
	Structs   []Struct    // Structs as named types.
	Ints      []Ints      // Int enums as named types.
	Strings   []Strings   // String enums used as named types.

	Version          string `json:",omitempty"` // Version if this API, only relevant for the top-level section of an API. Typically filled in by server at startup.
	SherpaVersion    int    // Version of sherpa this API implements. Currently at 0. Typically filled in by server at startup.
	SherpadocVersion int    `json:",omitempty"` // Version of the sherpadoc format. Currently at 1, the first defined version. Only relevant for the top-level section of an API.
}

// Function contains the documentation for a single function.
type Function struct {
	Name    string // Name of the function.
	Docs    string // Text or markdown, describing the function, its parameters, return types and possible errors.
	Params  []Arg
	Returns []Arg
}

// Arg is the name and type of a function parameter or return value.
//
// Production rules:
//
//	basictype := "bool" | "int8", "uint8" | "int16" | "uint16" | "int32" | "uint32" | "int64" | "uint64" | "int64s" | "uint64s" | "float32" | "float64" | "string" | "timestamp"
//	array := "[]"
//	map := "{}"
//	identifier := [a-zA-Z][a-zA-Z0-9]*
//	type := "nullable"? ("any" | basictype | identifier | array type | map type)
//
// It is not possible to have inline structs in an Arg. Those must be encoded as a
// named type.
type Arg struct {
	Name      string   // Name of the argument.
	Typewords []string // Typewords is an array of tokens describing the type.
}

// Struct is a named compound type.
type Struct struct {
	Name   string
	Docs   string
	Fields []Field
}

// Field is a single field of a struct type.
// The type can reference another named type.
type Field struct {
	Name      string
	Docs      string
	Typewords []string
}

// Ints is a type representing an enum with integers as types.
type Ints struct {
	Name   string
	Docs   string
	Values []struct {
		Name  string
		Value int
		Docs  string
	}
}

// Strings is a type representing an enum with strings as values.
type Strings struct {
	Name   string
	Docs   string
	Values []struct {
		Name  string
		Value string
		Docs  string
	}
}
