// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0

package configuration

import (
	"flag"
	"reflect"
	"strconv"
)

// AddFileFromFlagSet adds a file to the configuration
// The file is read from the flag specified by the name
func (s *Settings[C]) AddFileFromFlagSet(flagset *flag.FlagSet, name string, format Format) *Settings[C] {

	flag := flagset.Lookup(name)
	if flag == nil {
		s.errors = append(s.errors, newFlagDoesNotExistError(name))
		return s
	}

	path := flag.Value.String()
	if path == "" {
		s.errors = append(s.errors, FileNameEmptyError)
		return s
	}

	return s.AddFile(path, format)
}

// InitFromFlagSet initializes the configuration from the command line flags.
func (s *Settings[C]) InitFromFlagSet(flagset *flag.FlagSet) *Settings[C] {
	s.Lock()
	defer s.Unlock()

	err := runOnTags(&s.config, []string{flagTagKey}, func(k string, field reflect.Value) {

		flag := flagset.Lookup(k)
		if flag == nil {
			s.errors = append(s.errors, newFlagNotFoundError(k))
			return // flag not found
		}

		v := flag.Value
		t := reflect.TypeOf(v)

		if !field.CanSet() {
			return
		}

		switch field.Kind() {
		case reflect.String:
			field.SetString(v.String())
		case reflect.Int:
			intVar, err := strconv.Atoi(v.String())
			if err != nil {
				s.errors = append(s.errors, err)
				return
			}
			field.SetInt(int64(intVar))
		case reflect.Bool:
			field.SetBool(v.String() == "true")
		default:
			s.errors = append(s.errors, newMismatchedTypeError(t, field.Type()))
		}

	})

	if err != nil {
		s.errors = append(s.errors, err)
	}

	return s
}