package comparison

import (
	"encoding/json"
)

type ComparableResults interface {
	ResetResults()
	NextResultFromPath([]string) interface{}
}

func singleComparableFromJSONObj(obj interface{}) ComparableResults {
	tryMap, ok := obj.(map[string]interface{})
	if ok {
		internalMap := make(map[string]ComparableResults)
		for key, value := range tryMap {
			internalMap[key] = singleComparableFromJSONObj(value)
		}

		return &ComparableMap{internalValue: internalMap}
	}

	tryArray, ok := obj.([]interface{})
	if ok {
		internalArray := make([]ComparableResults, 0)
		for _, value := range tryArray {
			internalArray = append(internalArray, singleComparableFromJSONObj(value))
		}

		return &ComparableArray{internalValue: internalArray}
	}

	return &ComparableValue{internalValue: obj}
}

func ComparablesFromJSONObj(objs []interface{}) []ComparableResults {
	output := []ComparableResults{}

	for _, obj := range objs {
		output = append(output, singleComparableFromJSONObj(obj))
	}

	return output
}

func ComparablesFromStruct(inputStruct []interface{}) ([]ComparableResults, error) {
	output := []ComparableResults{}

	resultBytes, err := json.Marshal(inputStruct)
	if err != nil {
		return output, err
	}

	var jsonObj []interface{}
	err = json.Unmarshal(resultBytes, &jsonObj)
	if err != nil {
		return output, err
	}

	return ComparablesFromJSONObj(jsonObj), nil
}
