package main

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"

	"github.com/orchard9/rdev/internal/sdlc"
	"github.com/spf13/cobra"
)

var (
	rootDir    string
	jsonOutput bool
)

var rootCmd = &cobra.Command{
	Use:   "sdlc",
	Short: "Deterministic SDLC orchestration tool",
	Long:  "Manage the software development lifecycle with deterministic state, artifacts, and classification.",
}

func init() {
	rootCmd.PersistentFlags().StringVar(&rootDir, "root", "", "project root (default: auto-detect)")
	rootCmd.PersistentFlags().BoolVar(&jsonOutput, "json", false, "output as JSON")
}

// resolveRoot finds the project root by looking for .sdlc/ or .git/ walking up.
func resolveRoot() (string, error) {
	if rootDir != "" {
		abs, err := filepath.Abs(rootDir)
		if err != nil {
			return "", fmt.Errorf("resolve root: %w", err)
		}
		return abs, nil
	}

	dir, err := os.Getwd()
	if err != nil {
		return "", fmt.Errorf("get working directory: %w", err)
	}

	for {
		if sdlc.IsInitialized(dir) {
			return dir, nil
		}
		if _, err := os.Stat(filepath.Join(dir, ".git")); err == nil {
			return dir, nil
		}
		parent := filepath.Dir(dir)
		if parent == dir {
			break
		}
		dir = parent
	}

	// Fall back to cwd
	cwd, _ := os.Getwd()
	return cwd, nil
}

// mustResolveRoot resolves root or panics (for use in RunE where error is returned).
// Note: Panicking here is intentional as these commands run under cobra which
// catches panics and converts them to errors. For production use, prefer resolveRoot().
func mustResolveRoot() string {
	root, err := resolveRoot()
	if err != nil {
		panic(fmt.Sprintf("resolve root: %v", err))
	}
	return root
}

// printJSON marshals v as indented JSON and prints to stdout.
// Returns an error if marshaling fails instead of exiting.
func printJSON(v any) error {
	data, err := json.MarshalIndent(v, "", "  ")
	if err != nil {
		return fmt.Errorf("marshal JSON: %w", err)
	}
	fmt.Println(string(data))
	return nil
}
