package main

import (
	"fmt"
	"os"

	"gopkg.in/yaml.v3"
)

type Capability struct {
	Name             string   `yaml:"name"`
	BinariesAllowed  []string `yaml:"binaries_allowed,omitempty"`
	PathsAllowed     []string `yaml:"paths_allowed,omitempty"`
	RequiresApproval bool     `yaml:"requires_approval"`
	// shell.eval specific fields
	Blocklist      []string `yaml:"blocklist,omitempty"`        // regex patterns hardcoded + extendible
	AutoApprove    []string `yaml:"auto_approve,omitempty"`     // regex patterns pre-approved
	ShellMode      string   `yaml:"shell_mode,omitempty"`       // "bash"|"powershell"|"auto" (default auto)
	MaxOutputBytes int      `yaml:"max_output_bytes,omitempty"` // default 1MB
	TimeoutSeconds int      `yaml:"timeout_seconds,omitempty"`  // default 60
	// browser.* specific fields (CDP)
	ChromeCDPHost string `yaml:"chrome_cdp_host,omitempty"` // default 127.0.0.1
	ChromeCDPPort int    `yaml:"chrome_cdp_port,omitempty"` // default 9223
	ScreenshotDir string `yaml:"screenshot_dir,omitempty"`  // dest dir for screenshots (browser.screenshot)
}

type Manifest struct {
	DeviceID     string       `yaml:"device_id"`
	Operator     string       `yaml:"operator"`
	Capabilities []Capability `yaml:"capabilities"`
}

func LoadManifest(path string) (*Manifest, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("read manifest %s: %w", path, err)
	}
	var mf Manifest
	if err := yaml.Unmarshal(data, &mf); err != nil {
		return nil, fmt.Errorf("parse manifest yaml: %w", err)
	}
	if mf.DeviceID == "" {
		return nil, fmt.Errorf("manifest missing device_id")
	}
	if len(mf.Capabilities) == 0 {
		return nil, fmt.Errorf("manifest has no capabilities")
	}
	return &mf, nil
}

// CapabilityByName devuelve el bloque del manifest para name, o nil si no esta.
func (m *Manifest) CapabilityByName(name string) *Capability {
	for i := range m.Capabilities {
		if m.Capabilities[i].Name == name {
			return &m.Capabilities[i]
		}
	}
	return nil
}
