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 }