/*
 *
 * Copyright 2019 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

/*
Package flags provide convenience types and routines to accept specific types
of flag values on the command line.
*/
package flags

import (
	"bytes"
	"encoding/csv"
	"flag"
	"fmt"
	"strconv"
	"strings"
	"time"
)

// stringFlagWithAllowedValues represents a string flag which can only take a
// predefined set of values.
type stringFlagWithAllowedValues struct {
	val     string
	allowed []string
}

// StringWithAllowedValues returns a flag variable of type
// stringFlagWithAllowedValues configured with the provided parameters.
// 'allowed` is the set of values that this flag can be set to.
func StringWithAllowedValues(name, defaultVal, usage string, allowed []string) *string {
	as := &stringFlagWithAllowedValues{defaultVal, allowed}
	flag.CommandLine.Var(as, name, usage)
	return &as.val
}

// String implements the flag.Value interface.
func (as *stringFlagWithAllowedValues) String() string {
	return as.val
}

// Set implements the flag.Value interface.
func (as *stringFlagWithAllowedValues) Set(val string) error {
	for _, a := range as.allowed {
		if a == val {
			as.val = val
			return nil
		}
	}
	return fmt.Errorf("want one of: %v", strings.Join(as.allowed, ", "))
}

type durationSliceValue []time.Duration

// DurationSlice returns a flag representing a slice of time.Duration objects.
func DurationSlice(name string, defaultVal []time.Duration, usage string) *[]time.Duration {
	ds := make([]time.Duration, len(defaultVal))
	copy(ds, defaultVal)
	dsv := (*durationSliceValue)(&ds)
	flag.CommandLine.Var(dsv, name, usage)
	return &ds
}

// Set implements the flag.Value interface.
func (dsv *durationSliceValue) Set(s string) error {
	ds := strings.Split(s, ",")
	var dd []time.Duration
	for _, n := range ds {
		d, err := time.ParseDuration(n)
		if err != nil {
			return err
		}
		dd = append(dd, d)
	}
	*dsv = durationSliceValue(dd)
	return nil
}

// String implements the flag.Value interface.
func (dsv *durationSliceValue) String() string {
	var b bytes.Buffer
	for i, d := range *dsv {
		if i > 0 {
			b.WriteRune(',')
		}
		b.WriteString(d.String())
	}
	return b.String()
}

type intSliceValue []int

// IntSlice returns a flag representing a slice of ints.
func IntSlice(name string, defaultVal []int, usage string) *[]int {
	is := make([]int, len(defaultVal))
	copy(is, defaultVal)
	isv := (*intSliceValue)(&is)
	flag.CommandLine.Var(isv, name, usage)
	return &is
}

// Set implements the flag.Value interface.
func (isv *intSliceValue) Set(s string) error {
	is := strings.Split(s, ",")
	var ret []int
	for _, n := range is {
		i, err := strconv.Atoi(n)
		if err != nil {
			return err
		}
		ret = append(ret, i)
	}
	*isv = intSliceValue(ret)
	return nil
}

// String implements the flag.Value interface.
func (isv *intSliceValue) String() string {
	var b bytes.Buffer
	for i, n := range *isv {
		if i > 0 {
			b.WriteRune(',')
		}
		b.WriteString(strconv.Itoa(n))
	}
	return b.String()
}

type stringSliceValue []string

// StringSlice returns a flag representing a slice of strings.
func StringSlice(name string, defaultVal []string, usage string) *[]string {
	ss := make([]string, len(defaultVal))
	copy(ss, defaultVal)
	ssv := (*stringSliceValue)(&ss)
	flag.CommandLine.Var(ssv, name, usage)
	return &ss
}

// escapedCommaSplit splits a comma-separated list of strings in the same way
// CSV files work (escaping a comma requires double-quotes).
func escapedCommaSplit(str string) ([]string, error) {
	r := csv.NewReader(strings.NewReader(str))
	ret, err := r.Read()
	if err != nil {
		return nil, err
	}
	return ret, nil
}

// Set implements the flag.Value interface.
func (ss *stringSliceValue) Set(str string) error {
	var err error
	*ss, err = escapedCommaSplit(str)
	if err != nil {
		return err
	}
	return nil
}

// String implements the flag.Value interface.
func (ss *stringSliceValue) String() string {
	return strings.Join(*ss, ",")
}
