// Package paths resolves on-disk locations for the v0.9 multi-namespace
// filesystem layout (R-002). It is the canonical source of truth for
// cluster-wide, per-namespace, and CLI-cache paths.
//
// The v0.8 internal/certpaths package is preserved as a thin shim that
// returns the legacy flat-layout paths during the v0.9 dual-write window
// (REQ-090). New code should use internal/paths, NOT certpaths.
package paths

import (
	"os"
	"path/filepath"
)

const (
	defaultHomeSubdir = ".orca"
	clusterDirName    = "cluster"
	defaultNamespace  = "_defaults"
)

// Root returns the ORCA home directory. It honors $ORCA_HOME for
// testability; otherwise it defaults to ~/.orca. An empty $ORCA_HOME is
// treated as unset.
func Root() string {
	if p := os.Getenv("ORCA_HOME"); p != "" {
		return p
	}
	home, _ := os.UserHomeDir()
	return filepath.Join(home, defaultHomeSubdir)
}

// ClusterDir returns the cluster-wide directory: Root()/cluster.
// Cluster-wide artifacts (CA, master key, peers, txns, known_hosts, SSH
// keys) live here and are NOT scoped to a workload namespace (R-002).
func ClusterDir() string { return filepath.Join(Root(), clusterDirName) }

// NamespaceDir returns the directory for a namespace: Root()/<ns>.
// Use DefaultNamespace() for the implicit root namespace (R-002 D-159).
func NamespaceDir(ns string) string { return filepath.Join(Root(), ns) }

// NSDb returns the SQLite database path for a namespace:
// NamespaceDir(ns)/db/orca.db.
func NSDb(ns string) string { return filepath.Join(NamespaceDir(ns), "db", "orca.db") }

// NSEnv returns the .env path for a namespace: NamespaceDir(ns)/.env.
func NSEnv(ns string) string { return filepath.Join(NamespaceDir(ns), ".env") }

// NSSecrets returns the encrypted secrets env path for a namespace:
// NamespaceDir(ns)/.env.secrets.
func NSSecrets(ns string) string { return filepath.Join(NamespaceDir(ns), ".env.secrets") }

// NSJobs returns the jobs directory for a namespace: NamespaceDir(ns)/jobs.
func NSJobs(ns string) string { return filepath.Join(NamespaceDir(ns), "jobs") }

// NSAlloc returns the allocation directory for a namespace:
// NamespaceDir(ns)/alloc.
func NSAlloc(ns string) string { return filepath.Join(NamespaceDir(ns), "alloc") }

// NSMd returns the namespace Markdown doc path (R-014):
// NamespaceDir(ns)/ns.md.
func NSMd(ns string) string { return filepath.Join(NamespaceDir(ns), "ns.md") }

// DefaultNamespace returns the implicit root namespace name (R-002 D-159).
func DefaultNamespace() string { return defaultNamespace }

// CACertPath returns the v0.9 cluster CA cert path:
// ClusterDir()/ca.crt (D-101). The v0.8 internal CA still writes to
// Root()/ca.crt; the move happens in v0.10-P14.
func CACertPath() string { return filepath.Join(ClusterDir(), "ca.crt") }

// CAKeyPath returns the v0.9 cluster CA key path:
// ClusterDir()/ca.key.
func CAKeyPath() string { return filepath.Join(ClusterDir(), "ca.key") }

// MasterKeyPath returns the AES-256-GCM root master key path
// (R-011, mode 0600): ClusterDir()/master.key. Not generated until
// v0.10-P03.
func MasterKeyPath() string { return filepath.Join(ClusterDir(), "master.key") }

// CacheDB returns the CLI-side cache database path (R-008):
// Root()/orca_cache.db. Not created until v0.9-P0a2.
func CacheDB() string { return filepath.Join(Root(), "orca_cache.db") }

// TxnDir returns the cluster transaction log directory (R-016):
// ClusterDir()/txns.
func TxnDir() string { return filepath.Join(ClusterDir(), "txns") }

// PeersDir returns the cluster peers directory: ClusterDir()/peers.
func PeersDir() string { return filepath.Join(ClusterDir(), "peers") }

// PeerDir returns the directory for a single peer host:
// PeersDir()/host.
func PeerDir(host string) string { return filepath.Join(PeersDir(), host) }

// KnownHostsPath returns the SSH known_hosts path (D-035):
// ClusterDir()/known_hosts.
func KnownHostsPath() string { return filepath.Join(ClusterDir(), "known_hosts") }

// SSHKeyPath returns the orca SSH private key path:
// ClusterDir()/orca_ssh_key (D-037).
func SSHKeyPath() string { return filepath.Join(ClusterDir(), "orca_ssh_key") }

// SSHPubPath returns the orca SSH public key path:
// ClusterDir()/orca_ssh_key.pub.
func SSHPubPath() string { return filepath.Join(ClusterDir(), "orca_ssh_key.pub") }

// ServerCertPath returns the legacy server cert path (legacy compat):
// ClusterDir()/server.crt. step-ca will replace this in a later phase.
func ServerCertPath() string { return filepath.Join(ClusterDir(), "server.crt") }

// ServerKeyPath returns the legacy server key path (legacy compat):
// ClusterDir()/server.key. step-ca will replace this in a later phase.
func ServerKeyPath() string { return filepath.Join(ClusterDir(), "server.key") }

// ConfigPath returns the new Markdown-frontmatter config path (R-014):
// ClusterDir()/config.md. The legacy HCL path is ClusterDir()/config.hcl.
func ConfigPath() string { return filepath.Join(ClusterDir(), "config.md") }

// LegacyHCLConfigPath returns the legacy HCL config path:
// ClusterDir()/config.hcl.
func LegacyHCLConfigPath() string { return filepath.Join(ClusterDir(), "config.hcl") }

// ACLPath returns the cluster-wide ACL state file (P02, v0.11):
// ClusterDir()/acl.json. A simple JSON file — no DB needed for v0.11.
func ACLPath() string { return filepath.Join(ClusterDir(), "acl.json") }
