package adk

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/orchard9/stemedb-go/steme"
)

// ConstraintCheckTool provides pre-flight validation for Implementation Agent.
//
// Returns must-use and forbidden patterns for a given context.
type ConstraintCheckTool struct {
	client EpistemeClient
}

// NewConstraintCheckTool creates a new ConstraintCheck tool.
func NewConstraintCheckTool(client EpistemeClient) *ConstraintCheckTool {
	return &ConstraintCheckTool{client: client}
}

// Name returns the tool name.
func (t *ConstraintCheckTool) Name() string {
	return "episteme_constraint_check"
}

// Description returns the tool description.
func (t *ConstraintCheckTool) Description() string {
	return "Check for must-use and forbidden patterns before code generation. " +
		"Returns constraints with explanations for contrastive learning. " +
		"Implementation Agent MUST call this before writing code."
}

// Execute performs the constraint check.
func (t *ConstraintCheckTool) Execute(ctx context.Context, input []byte) ([]byte, error) {
	var params ConstraintCheckInput
	if err := json.Unmarshal(input, &params); err != nil {
		return nil, fmt.Errorf("invalid constraint check input: %w", err)
	}

	// Query for constraints in the given context
	// This queries for assertions with predicate "must_use" or "forbidden"
	builder := steme.NewQuery().
		WithSubject(params.Context).
		WithLifecycle(steme.LifecycleApproved). // Only approved constraints
		WithLens(steme.LensAuthority)

	result, err := t.client.Query(ctx, builder.Build())
	if err != nil {
		return nil, fmt.Errorf("constraint query failed: %w", err)
	}

	// Convert assertions to constraints
	constraints := convertToConstraints(result)

	outputBytes, err := json.Marshal(ConstraintCheckOutput{
		Constraints: constraints,
	})
	if err != nil {
		return nil, fmt.Errorf("failed to marshal constraint output: %w", err)
	}
	return outputBytes, nil
}
