package devcontainer

import (
	"fmt"
	"log"
	"strings"

	"zlh-agent/internal/state"

	"zlh-agent/internal/provision/devcontainer/dotnet"
	devgo "zlh-agent/internal/provision/devcontainer/go"
	"zlh-agent/internal/provision/devcontainer/java"
	"zlh-agent/internal/provision/devcontainer/node"
	"zlh-agent/internal/provision/devcontainer/python"
)

func Provision(cfg state.Config) error {
	log.Printf("[provision] vmid=%d type=dev runtime=%s version=%s action=dev_provision status=begin", cfg.VMID, cfg.Runtime, cfg.Version)
	if err := ValidateRuntimeSelection(cfg); err != nil {
		log.Printf("[provision] vmid=%d type=dev runtime=%s version=%s action=dev_provision status=failed err=%v", cfg.VMID, cfg.Runtime, cfg.Version, err)
		return err
	}
	if err := EnsureDevUserEnvironment(); err != nil {
		log.Printf("[provision] vmid=%d type=dev runtime=%s version=%s action=ensure_dev_user status=failed err=%v", cfg.VMID, cfg.Runtime, cfg.Version, err)
		return err
	}

	runtime := strings.ToLower(cfg.Runtime)

	var err error
	switch runtime {
	case "node":
		err = node.Install(cfg)
	case "python":
		err = python.Install(cfg)
	case "go":
		err = devgo.Install(cfg)
	case "java":
		err = java.Install(cfg)
	case "dotnet":
		err = dotnet.Install(cfg)
	default:
		return fmt.Errorf("unsupported dev container runtime: %s", runtime)
	}

	if err != nil {
		log.Printf("[provision] vmid=%d type=dev runtime=%s version=%s action=runtime_install status=failed err=%v", cfg.VMID, cfg.Runtime, cfg.Version, err)
		return err
	}
	if err := WriteReadyMarker(runtime); err != nil {
		log.Printf("[provision] vmid=%d type=dev runtime=%s version=%s action=write_ready_marker status=failed err=%v", cfg.VMID, cfg.Runtime, cfg.Version, err)
		return fmt.Errorf("write dev ready marker: %w", err)
	}
	log.Printf("[provision] vmid=%d type=dev runtime=%s version=%s action=dev_provision status=ok", cfg.VMID, cfg.Runtime, cfg.Version)
	return nil
}
