package preproc

// PragmaSet is an immutable snapshot of pragma name->value mappings.
type PragmaSet struct {
	m map[string]string
}

// GetPragma returns the value for name or "" if not present.
func (ps PragmaSet) GetPragma(name string) string {
	if v, ok := ps.m[name]; ok {
		return v
	}
	return ""
}

// For mocking
func NewPragmaSet(m map[string]string) PragmaSet {
	return PragmaSet{m: m}
}

// Pragma manages an immutable stack of PragmaSet snapshots.
type Pragma struct {
	pragmaSetStack []PragmaSet
}

func NewPragma() *Pragma {
	return &Pragma{
		pragmaSetStack: []PragmaSet{{m: make(map[string]string)}},
	}
}

// AddPragma adds or replaces a pragma by name.
func (p *Pragma) AddPragma(name, value string) {
	last := p.pragmaSetStack[len(p.pragmaSetStack)-1].m
	newMap := make(map[string]string, len(last)+1)
	for k, v := range last {
		newMap[k] = v
	}
	newMap[name] = value
	p.pragmaSetStack = append(p.pragmaSetStack, PragmaSet{m: newMap})
}

func (p *Pragma) GetCurrentPragmaSetIndex() int {
	return len(p.pragmaSetStack) - 1
}

func (p *Pragma) GetPragmaSetByIndex(index int) PragmaSet {
	return p.pragmaSetStack[index] // panics if bad
}
