package cli

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
	"path/filepath"
	"strings"
	"time"
)

type RunIDGenerator func(time.Time) (string, error)

func defaultRunIDGenerator(startedAt time.Time) (string, error) {
	var suffix [16]byte
	if _, err := io.ReadFull(rand.Reader, suffix[:]); err != nil {
		return "", fmt.Errorf("read random run ID suffix: %w", err)
	}
	return fmt.Sprintf("run-%d-%s", startedAt.UnixNano(), hex.EncodeToString(suffix[:])), nil
}

func validateRunID(runID string) error {
	if runID == "" {
		return fmt.Errorf("run ID must not be empty")
	}
	if runID != strings.TrimSpace(runID) {
		return fmt.Errorf("run ID %q must not have surrounding whitespace", runID)
	}
	if strings.ContainsAny(runID, `/\\`) || filepath.IsAbs(runID) || filepath.Clean(runID) != runID || runID == "." || runID == ".." {
		return fmt.Errorf("run ID %q must be one safe path component", runID)
	}
	return nil
}
