package ast

import (
	"fmt"
	"sort"
	"strings"
	"time"
)

// String() produces a JSON-like (but not JSON) string representation of the TOML Document.
// This string version is mainly useful for testing and debugging purposes.
func (t Table) String() string {
	return NewValue(TypeTable, t).String()
}

// String() produces a JSON-like (but not JSON) string representation of the value.
// This string version is mainly useful for testing and debugging purposes.
func (value Value) String() string {
	data := value.Data[0]
	switch value.Type {
	case TypeString:
		return fmt.Sprintf("%q", data)
	case TypeOffsetDateTime:
		return data.(time.Time).Format(time.RFC3339Nano)
	case TypeLocalDateTime:
		return data.(time.Time).Format("2006-01-02 15:04:05.999999999")
	case TypeLocalDate:
		return data.(time.Time).Format("2006-01-02")
	case TypeLocalTime:
		return data.(time.Time).Format("15:04:05.999999999")
	case TypeArrayOfTables:
		fallthrough
	case TypeArray:
		a := data.(*Array)
		values := make([]string, 0, a.Length)
		for i := a.First; i != nil; i = i.Next {
			values = append(values, i.Value.String())
		}
		return fmt.Sprintf("[%s]", strings.Join(values, ", "))
	case TypeImplicitTable:
		fallthrough
	case TypeTable:
		pairs := data.(Table)
		keys := make([]string, len(pairs))
		i := 0
		for k := range pairs {
			keys[i] = k
			i++
		}
		sort.Strings(keys)
		values := make([]string, len(pairs))
		for i, k := range keys {
			values[i] = fmt.Sprintf("%q: %s", k, pairs[k].String())
		}
		return fmt.Sprintf("{%s}", strings.Join(values, ", "))
	default:
		return fmt.Sprintf("%v", data)
	}
}
