// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package schema

import (
	"fmt"
	"strings"
)

// MapFieldReader reads fields out of an untyped map[string]string to
// the best of its ability.
type MapFieldReader struct {
	Map    MapReader
	Schema map[string]*Schema
}

func (r *MapFieldReader) ReadField(address []string) (FieldReadResult, error) {
	k := strings.Join(address, ".")
	schemaList := addrToSchema(address, r.Schema)
	if len(schemaList) == 0 {
		return FieldReadResult{}, nil
	}

	schema := schemaList[len(schemaList)-1]
	switch schema.Type {
	case TypeBool, TypeInt, TypeFloat, TypeString:
		return r.readPrimitive(address, schema)
	case TypeList:
		return readListField(r, address, schema)
	case TypeMap:
		return r.readMap(k, schema)
	case TypeSet:
		return r.readSet(address, schema)
	case typeObject:
		return readObjectField(r, address, schema.Elem.(map[string]*Schema))
	default:
		panic(fmt.Sprintf("Unknown type: %s", schema.Type))
	}
}

func (r *MapFieldReader) readMap(k string, schema *Schema) (FieldReadResult, error) {
	result := make(map[string]interface{})
	resultSet := false

	// If the name of the map field is directly in the map with an
	// empty string, it means that the map is being deleted, so mark
	// that is is set.
	if v, ok := r.Map.Access(k); ok && v == "" {
		resultSet = true
	}

	prefix := k + "."
	r.Map.Range(func(k, v string) bool {
		if strings.HasPrefix(k, prefix) {
			resultSet = true

			key := k[len(prefix):]
			if key != "%" && key != "#" {
				result[key] = v
			}
		}

		return true
	})

	err := mapValuesToPrimitive(k, result, schema)
	if err != nil {
		return FieldReadResult{}, nil
	}

	var resultVal interface{}
	if resultSet {
		resultVal = result
	}

	return FieldReadResult{
		Value:  resultVal,
		Exists: resultSet,
	}, nil
}

func (r *MapFieldReader) readPrimitive(
	address []string, schema *Schema) (FieldReadResult, error) {
	k := strings.Join(address, ".")
	result, ok := r.Map.Access(k)
	if !ok {
		return FieldReadResult{}, nil
	}

	returnVal, err := stringToPrimitive(result, false, schema)
	if err != nil {
		return FieldReadResult{}, err
	}

	return FieldReadResult{
		Value:  returnVal,
		Exists: true,
	}, nil
}

func (r *MapFieldReader) readSet(
	address []string, schema *Schema) (FieldReadResult, error) {
	// copy address to ensure we don't modify the argument
	address = append([]string(nil), address...)

	// Get the number of elements in the list
	countRaw, err := r.readPrimitive(
		append(address, "#"), &Schema{Type: TypeInt})
	if err != nil {
		return FieldReadResult{}, err
	}
	if !countRaw.Exists {
		// No count, means we have no list
		countRaw.Value = 0
	}

	// Create the set that will be our result
	set := schema.ZeroValue().(*Set)

	// If we have an empty list, then return an empty list
	if countRaw.Computed || countRaw.Value.(int) == 0 {
		return FieldReadResult{
			Value:    set,
			Exists:   countRaw.Exists,
			Computed: countRaw.Computed,
		}, nil
	}

	// Go through the map and find all the set items
	prefix := strings.Join(address, ".") + "."
	countExpected := countRaw.Value.(int)
	countActual := make(map[string]struct{})
	completed := r.Map.Range(func(k, _ string) bool {
		if !strings.HasPrefix(k, prefix) {
			return true
		}
		if strings.HasPrefix(k, prefix+"#") {
			// Ignore the count field
			return true
		}

		// Split the key, since it might be a sub-object like "idx.field"
		parts := strings.Split(k[len(prefix):], ".")
		idx := parts[0]

		var raw FieldReadResult
		raw, err = r.ReadField(append(address, idx))
		if err != nil {
			return false
		}
		if !raw.Exists {
			// This shouldn't happen because we just verified it does exist
			panic("missing field in set: " + k + "." + idx)
		}

		set.Add(raw.Value)

		// Due to the way multimap readers work, if we've seen the number
		// of fields we expect, then exit so that we don't read later values.
		// For example: the "set" map might have "ports.#", "ports.0", and
		// "ports.1", but the "state" map might have those plus "ports.2".
		// We don't want "ports.2"
		countActual[idx] = struct{}{}
		if len(countActual) >= countExpected {
			return false
		}

		return true
	})
	if !completed && err != nil {
		return FieldReadResult{}, err
	}

	return FieldReadResult{
		Value:  set,
		Exists: true,
	}, nil
}

// MapReader is an interface that is given to MapFieldReader for accessing
// a "map". This can be used to have alternate implementations. For a basic
// map[string]string, use BasicMapReader.
type MapReader interface {
	Access(string) (string, bool)
	Range(func(string, string) bool) bool
}

// BasicMapReader implements MapReader for a single map.
type BasicMapReader map[string]string

func (r BasicMapReader) Access(k string) (string, bool) {
	v, ok := r[k]
	return v, ok
}

func (r BasicMapReader) Range(f func(string, string) bool) bool {
	for k, v := range r {
		if cont := f(k, v); !cont {
			return false
		}
	}

	return true
}

// MultiMapReader reads over multiple maps, preferring keys that are
// founder earlier (lower number index) vs. later (higher number index)
type MultiMapReader []map[string]string

func (r MultiMapReader) Access(k string) (string, bool) {
	for _, m := range r {
		if v, ok := m[k]; ok {
			return v, ok
		}
	}

	return "", false
}

func (r MultiMapReader) Range(f func(string, string) bool) bool {
	done := make(map[string]struct{})
	for _, m := range r {
		for k, v := range m {
			if _, ok := done[k]; ok {
				continue
			}

			if cont := f(k, v); !cont {
				return false
			}

			done[k] = struct{}{}
		}
	}

	return true
}
