// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause

//go:build !plan9

// Package kube contains types and utilities for the Tailscale Kubernetes Operator.
package kube

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"

	"tailscale.com/tailcfg"
)

const (
	Alpha1Version = "v1alpha1"

	DNSRecordsCMName = "dnsrecords"
	DNSRecordsCMKey  = "records.json"
)

type Records struct {
	// Version is the version of this Records configuration. Version is
	// written by the operator, i.e when it first populates the Records.
	// k8s-nameserver must verify that it knows how to parse a given
	// version.
	Version string `json:"version"`
	// IP4 contains a mapping of DNS names to IPv4 address(es).
	IP4 map[string][]string `json:"ip4"`
	// IP6 contains a mapping of DNS names to IPv6 address(es).
	// This field is optional and will be omitted from JSON if empty.
	// It enables dual-stack DNS support in Kubernetes clusters.
	// +optional
	IP6 map[string][]string `json:"ip6,omitempty"`
}

// TailscaledConfigFileName returns a tailscaled config file name in
// format expected by containerboot for the given CapVer.
func TailscaledConfigFileName(cap tailcfg.CapabilityVersion) string {
	return fmt.Sprintf("cap-%v.hujson", cap)
}

// CapVerFromFileName parses the capability version from a tailscaled
// config file name previously generated by TailscaledConfigFileNameForCap.
func CapVerFromFileName(name string) (tailcfg.CapabilityVersion, error) {
	if name == "tailscaled" {
		return 0, nil
	}
	var cap tailcfg.CapabilityVersion
	_, err := fmt.Sscanf(name, "cap-%d.hujson", &cap)
	return cap, err
}

// TruncateLabelValue truncates a Kubernetes label value to fit within the
// 63-character limit. If the value exceeds the limit, it is truncated and a
// short hash suffix is appended to preserve uniqueness.
func TruncateLabelValue(val string) string {
	const maxLen = 63
	if len(val) <= maxLen {
		return val
	}
	hash := sha256.Sum256([]byte(val))
	suffix := hex.EncodeToString(hash[:4]) // 8 hex chars
	truncated := val[:maxLen-len(suffix)-1]
	return truncated + "-" + suffix
}
