// MakeFileBase64Sha512Func constructs a function that is like Base64Sha512Func but reads the
// contents of a file rather than hashing a given literal string.
770664
func MakeFileBase64Sha512Func(baseDir string) function.Function {
	return makeFileHashFunction(baseDir, sha512.New, base64.StdEncoding.EncodeToString)
}
620758
func decodeBase64(s string) ([]byte, error) {
	for i := 0; i < len(s)%4; i++ {
		s += "="
	}
	return base64.URLEncoding.DecodeString(s)
}
1227685
func (p Protected) Base64() ([]byte, error) {
	b, err := json.Marshal(map[string]interface{}(p))
	if err != nil {
		return nil, err
	}
	return Base64Encode(b), nil
}
752619
func MakeFileFunc(baseDir string, encBase64 bool) function.Function {
	return function.New(&function.Spec{
		Params: []function.Parameter{
			{
				Name: "path",
				Type: cty.String,
			},
		},
		Type: function.StaticReturnType(cty.String),
		Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
			path := args[0].AsString()
			src, err := readFileBytes(baseDir, path)
			if err != nil {
				return cty.UnknownVal(cty.String), err
			}

			switch {
			case encBase64:
				enc := base64.StdEncoding.EncodeToString(src)
				return cty.StringVal(enc), nil
			default:
				if !utf8.Valid(src) {
					return cty.UnknownVal(cty.String), fmt.Errorf("contents of %s are not valid UTF-8; use the filebase64 function to obtain the Base64 encoded contents or the other file functions (e.g. filemd5, filesha256) to obtain file hashing results instead", path)
				}
				return cty.StringVal(string(src)), nil
			}
		},
	})
}
295034
func UUIDToBase64(uuid uuid.UUID) string {
	return base64.StdEncoding.EncodeToString([]byte(uuid))
}
829063
func Sha512(str cty.Value) (cty.Value, error) {
	return Sha512Func.Call([]cty.Value{str})
}
1259996
func HmacSHA512(key, origData []byte) (sum []byte) {
	mac := hmac.New(sha512.New, key)
	mac.Write(origData)
	return mac.Sum(nil)
}
1080543
func interpolationFuncBasename() ast.Function {
	return ast.Function{
		ArgTypes:   []ast.Type{ast.TypeString},
		ReturnType: ast.TypeString,
		Callback: func(args []interface{}) (interface{}, error) {
			return filepath.Base(args[0].(string)), nil
		},
	}
}
844415
func Sha512(master, salt, info []byte) ([32]byte, error) {
	hash := sha512.New
	hkdf := hkdf.New(hash, master, salt, info)

	key := make([]byte, 32) // 256 bit
	_, err := io.ReadFull(hkdf, key)

	var result [32]byte
	copy(result[:], key)

	return result, err
}
77623
func (f *CryptoFuncs) SHA512_224(input interface{}) string {
	in := toBytes(input)
	out := sha512.Sum512_224(in)
	return fmt.Sprintf("%02x", out)
}
766797
func interpolationFuncBase64Decode() ast.Function {
	return ast.Function{
		ArgTypes:   []ast.Type{ast.TypeString},
		ReturnType: ast.TypeString,
		Callback: func(args []interface{}) (interface{}, error) {
			s := args[0].(string)
			sDec, err := base64.StdEncoding.DecodeString(s)
			if err != nil {
				return "", fmt.Errorf("failed to decode base64 data '%s'", s)
			}
			return string(sDec), nil
		},
	}
}
823164
func sampleFloat64DecodeFunc(bitsPerSample int) (func([]byte) float64, error) {
	bytesPerSample := bitsPerSample / 8
	switch bytesPerSample {
	case 1:
		// 8bit values are unsigned
		return func(s []byte) float64 {
			return float64(uint8(s[0]))
		}, nil
	case 2:
		return func(s []byte) float64 {
			return float64(int(s[0]) + int(s[1])<<8)
		}, nil
	case 3:
		return func(s []byte) float64 {
			var output int32
			output |= int32(s[2]) << 0
			output |= int32(s[1]) << 8
			output |= int32(s[0]) << 16
			return float64(output)
		}, nil
	case 4:
		// TODO: fix the float64 conversion (current int implementation)
		return func(s []byte) float64 {
			return float64(int(s[0]) + int(s[1])<<8 + int(s[2])<<16 + int(s[3])<<24)
		}, nil
	default:
		return nil, fmt.Errorf("unhandled byte depth:%d", bitsPerSample)
	}
}
1325322
func (c *client) Base64Bytes(key string, fallback []byte) []byte {
	if s := c.Getenv(key); s != "" {
		if v, err := base64.StdEncoding.DecodeString(s); err == nil {
			return v
		}
	}

	return fallback
}
1353404
func Base64Encode(b []byte) []byte {
	buf := make([]byte, base64.RawURLEncoding.EncodedLen(len(b)))
	base64.RawURLEncoding.Encode(buf, b)
	return buf
}
698841
func globGetMakeFunction(files []string, suffix string, mode globMode) string {
	dirs := map[string]struct{}{}
	for _, file := range files {
		dirs[filepath.Dir(file)] = struct{}{}
	}
	makeWildcards := make([]string, 0, len(dirs))
	wildcard := globGetMakeSnippet(mode)
	for dir := range dirs {
		str := replacePlaceholders(wildcard, "SUFFIX", suffix, "DIR", dir)
		makeWildcards = append(makeWildcards, str)
	}
	return replacePlaceholders(globMakeFunction, "WILDCARDS", strings.Join(makeWildcards, " "))
}
1109926
func interpolationFuncBase64Gzip() ast.Function {
	return ast.Function{
		ArgTypes:   []ast.Type{ast.TypeString},
		ReturnType: ast.TypeString,
		Callback: func(args []interface{}) (interface{}, error) {
			s := args[0].(string)

			var b bytes.Buffer
			gz := gzip.NewWriter(&b)
			if _, err := gz.Write([]byte(s)); err != nil {
				return "", fmt.Errorf("failed to write gzip raw data: '%s'", s)
			}
			if err := gz.Flush(); err != nil {
				return "", fmt.Errorf("failed to flush gzip writer: '%s'", s)
			}
			if err := gz.Close(); err != nil {
				return "", fmt.Errorf("failed to close gzip writer: '%s'", s)
			}

			return base64.StdEncoding.EncodeToString(b.Bytes()), nil
		},
	}
}
199352
func AsUint64Function(env *Zlisp, name string, args []Sexp) (Sexp, error) {
	if len(args) != 1 {
		return SexpNull, WrongNargs
	}

	var val uint64
	switch x := args[0].(type) {
	case *SexpInt:
		val = uint64(x.Val)
	case *SexpFloat:
		val = uint64(x.Val)
	default:
		return SexpNull, fmt.Errorf("Cannot convert %s to uint64", TypeOf(args[0]).SexpString(nil))

	}
	return &SexpUint64{Val: val}, nil
}