hash-of-wisdom/internal/application/application.go

89 lines
2.8 KiB
Go

package application
import (
"context"
"fmt"
"io"
"hash-of-wisdom/internal/pow/challenge"
"hash-of-wisdom/internal/protocol"
"hash-of-wisdom/internal/quotes"
)
// Response represents an encodable response that can write itself to a connection
type Response interface {
Encode(w io.Writer) error
}
// WisdomService defines the interface for the wisdom service
type WisdomService interface {
GenerateChallenge(ctx context.Context, resource string) (*challenge.Challenge, error)
VerifySolution(ctx context.Context, solution *challenge.Solution) error
GetQuote(ctx context.Context) (*quotes.Quote, error)
}
// WisdomApplication handles the Word of Wisdom application logic
type WisdomApplication struct {
wisdomService WisdomService
}
// NewWisdomApplication creates a new wisdom application handler
func NewWisdomApplication(wisdomService WisdomService) *WisdomApplication {
return &WisdomApplication{
wisdomService: wisdomService,
}
}
// HandleMessage processes a protocol message and returns an encodable response
func (a *WisdomApplication) HandleMessage(ctx context.Context, msg *protocol.Message) (Response, error) {
switch msg.Type {
case protocol.ChallengeRequestType:
return a.handleChallengeRequest(ctx)
case protocol.SolutionRequestType:
return a.handleSolutionRequest(ctx, msg)
default:
return &protocol.ErrorResponse{
Code: protocol.ErrMalformedMessage,
Message: fmt.Sprintf("unsupported message type: 0x%02x", msg.Type),
}, nil
}
}
// handleChallengeRequest processes challenge requests
func (a *WisdomApplication) handleChallengeRequest(ctx context.Context) (Response, error) {
challenge, err := a.wisdomService.GenerateChallenge(ctx, "quotes")
if err != nil {
return &protocol.ErrorResponse{Code: protocol.ErrServerError, Message: "Contact administrator"}, nil
}
return &protocol.ChallengeResponse{Challenge: challenge}, nil
}
// handleSolutionRequest processes solution requests
func (a *WisdomApplication) handleSolutionRequest(ctx context.Context, msg *protocol.Message) (Response, error) {
// Parse solution request
var solutionReq protocol.SolutionRequest
if err := solutionReq.Decode(msg.PayloadStream); err != nil {
return &protocol.ErrorResponse{Code: protocol.ErrMalformedMessage, Message: "invalid solution format"}, nil
}
// Create solution object
solution := &challenge.Solution{
Challenge: solutionReq.Challenge,
Nonce: solutionReq.Nonce,
}
// Verify solution
if err := a.wisdomService.VerifySolution(ctx, solution); err != nil {
return &protocol.ErrorResponse{Code: protocol.ErrInvalidSolution, Message: "solution verification failed"}, nil
}
// Get quote
quote, err := a.wisdomService.GetQuote(ctx)
if err != nil {
return &protocol.ErrorResponse{Code: protocol.ErrServerError, Message: "Contact administrator"}, nil
}
return &protocol.SolutionResponse{Quote: quote}, nil
}