package gnmi

import (
	"fmt"
	"strconv"

	"github.com/openconfig/gnmi/proto/gnmi"
	gnmiv "github.com/openconfig/gnmi/value"
	"github.com/openconfig/goyang/pkg/yang"
)

// ConvertStringToGnmiTypedValue allows to convert a string into a
// gnmi.TypedValue; this conversion is based on the provided YANG type.
func ConvertStringToGnmiTypedValue(s string, t *yang.YangType) (*gnmi.TypedValue, error) {
	// TODO: add more types
	switch t.Kind {
	case yang.Yint8, yang.Yint16, yang.Yint32, yang.Yint64:
		return convertStringToIntTypedValue(s)
	case yang.Yuint8, yang.Yuint16, yang.Yuint32, yang.Yuint64:
		return convertStringToUintTypedValue(s)
	case yang.Ybool:
		parsedBool, err := strconv.ParseBool(s)
		if err != nil {
			return nil, err
		}
		return gnmiv.FromScalar(parsedBool)
	case yang.Ystring:
		return gnmiv.FromScalar(s)
	default:
		return nil, fmt.Errorf("could not convert to TypedValue, unsupported type of: %v", t)
	}
}

func convertStringToIntTypedValue(s string) (*gnmi.TypedValue, error) {
	parsedInt, err := strconv.ParseInt(s, 10, 64)
	if err != nil {
		return nil, err
	}
	return &gnmi.TypedValue{
		Value: &gnmi.TypedValue_IntVal{
			IntVal: int64(parsedInt),
		},
	}, nil
}

func convertStringToUintTypedValue(s string) (*gnmi.TypedValue, error) {
	parsedInt, err := strconv.ParseUint(s, 10, 64)
	if err != nil {
		return nil, err
	}
	return &gnmi.TypedValue{
		Value: &gnmi.TypedValue_UintVal{
			UintVal: uint64(parsedInt),
		},
	}, nil
}
