// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Utilities for building and parsing Sensor Log data keys.
package keyutil

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"strconv"
	"strings"
	"time"
)

const Sep = '$'

// Join joins key parts into key.
func Join(parts ...string) string {
	return strings.Join(parts, string(Sep))
}

// Split splits key into parts and verifies that the number of parts matches
// the expected number, returning an error otherwise.
func Split(key string, expectParts int) ([]string, error) {
	parts := strings.Split(key, string(Sep))
	if gotParts := len(parts); expectParts != gotParts {
		return nil, fmt.Errorf("invalid key %q: expected %d parts, got %d", key, expectParts, gotParts)
	}
	return parts, nil
}

func StringifyTime(t time.Time) string {
	return fmt.Sprintf("%016x", t.UnixNano())
}

func ParseTime(t string) (time.Time, error) {
	nsec, err := strconv.ParseInt(t, 16, 64)
	if err != nil {
		return time.Time{}, fmt.Errorf("failed parsing time: %v", err)
	}
	return time.Unix(0, nsec), nil
}

// ValidateId returns an error if the argument is not a valid identifier.
func ValidateId(id string) error {
	if id == "" {
		return fmt.Errorf("cannot be empty")
	}
	if strings.Contains(id, string(Sep)) {
		return fmt.Errorf("cannot contain %q", Sep)
	}
	return nil
}

// UUID generates a random UUID.
func UUID() string {
	uuid := make([]byte, 16)
	if _, err := rand.Read(uuid); err != nil {
		panic(fmt.Errorf("rng failed: %v", err))
	}
	// TODO(ivanpi): Use base64 once Syncbase keys are less restricted.
	return hex.EncodeToString(uuid)
}
