001/*
002 * SPDX-License-Identifier: Apache-2.0
003 *
004 * Copyright 2025-2026 The Enola <https://enola.dev> Authors
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *     https://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package dev.enola.audio.voice.twilio.relay;
019
020import com.fasterxml.jackson.annotation.JsonSubTypes;
021import com.fasterxml.jackson.annotation.JsonTypeInfo;
022
023import dev.enola.audio.voice.twilio.relay.ConversationRelayResponse.DTMF;
024import dev.enola.audio.voice.twilio.relay.ConversationRelayResponse.End;
025import dev.enola.audio.voice.twilio.relay.ConversationRelayResponse.Language;
026import dev.enola.audio.voice.twilio.relay.ConversationRelayResponse.Play;
027import dev.enola.audio.voice.twilio.relay.ConversationRelayResponse.Text;
028
029import java.net.URI;
030import java.util.Locale;
031
032/**
033 * Twilio's <a
034 * href="https://www.twilio.com/docs/voice/conversationrelay/websocket-messages">ConversationRelay
035 * response messages</a> JSON format.
036 */
037@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
038@JsonSubTypes({
039    @JsonSubTypes.Type(value = Text.class, name = "text"),
040    @JsonSubTypes.Type(value = Play.class, name = "play"),
041    @JsonSubTypes.Type(value = DTMF.class, name = "sendDigits"),
042    @JsonSubTypes.Type(value = Language.class, name = "language"),
043    @JsonSubTypes.Type(value = End.class, name = "end")
044})
045public sealed interface ConversationRelayResponse {
046
047    record Text(String token, Locale lang, boolean last, boolean interruptible, boolean preemptible)
048            implements ConversationRelayResponse {}
049
050    record Play(URI source, boolean interruptible, boolean preemptible)
051            implements ConversationRelayResponse {}
052
053    record DTMF(String digits) implements ConversationRelayResponse {}
054
055    record Language(Locale ttsLanguage, Locale transcriptionLanguage)
056            implements ConversationRelayResponse {}
057
058    // TODO Should handoffData be Map<String, Object> instead of String?
059    record End(String handoffData) implements ConversationRelayResponse {}
060}