001/*
002 *   Copyright 2024 Vonage
003 *
004 *   Licensed under the Apache License, Version 2.0 (the "License");
005 *   you may not use this file except in compliance with the License.
006 *   You may obtain a copy of the License at
007 *
008 *        http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *   Unless required by applicable law or agreed to in writing, software
011 *   distributed under the License is distributed on an "AS IS" BASIS,
012 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *   See the License for the specific language governing permissions and
014 *   limitations under the License.
015 */
016package com.vonage.client.users.channels;
017
018import com.fasterxml.jackson.annotation.*;
019import com.vonage.client.JsonableBaseObject;
020import com.vonage.client.common.ChannelType;
021
022/**
023 * Base class for channels.
024 */
025@JsonTypeInfo(
026        use = JsonTypeInfo.Id.NAME,
027        include = JsonTypeInfo.As.EXISTING_PROPERTY,
028        property = "type"
029)
030@JsonSubTypes({
031        @JsonSubTypes.Type(value = Messenger.class, name = "messenger"),
032        @JsonSubTypes.Type(value = Mms.class, name = "mms"),
033        @JsonSubTypes.Type(value = Pstn.class, names = {"phone", "pstn"}),
034        @JsonSubTypes.Type(value = Sip.class, name = "sip"),
035        @JsonSubTypes.Type(value = Sms.class, name = "sms"),
036        @JsonSubTypes.Type(value = Vbc.class, name = "vbc"),
037        @JsonSubTypes.Type(value = Viber.class, name = "viber"),
038        @JsonSubTypes.Type(value = Websocket.class, name = "websocket"),
039        @JsonSubTypes.Type(value = Whatsapp.class, name = "whatsapp"),
040        @JsonSubTypes.Type(value = WhatsappVoice.class, name = "whatsapp-voice")
041})
042public abstract class Channel extends JsonableBaseObject {
043    protected ChannelType type;
044
045    /**
046     * If the {@code type} field is present in JSON payload, returns the value as an enum.
047     * Usually however, the type can be inferred from the class name.
048     * This method is provided for completeness in cases where the field may be present.
049     *
050     * @return The channel type as an enum, or {@code null} if absent or not applicable in this context.
051     *
052     * @since 8.4.0
053     */
054    @JsonProperty("type")
055    public ChannelType getType() {
056        return type;
057    }
058
059    /**
060     * Sets the {@link #getType()} based on this class's type. This is useful for some API
061     * calls where the type information is expected to be present in the JSON.
062     *
063     * @since 8.4.0
064     * @see #removeTypeField()
065     */
066    @JsonIgnore
067    public void setTypeField() {
068        String name = getClass().getSimpleName();
069        if (name.equals("Pstn")) {
070            name = "Phone";
071        }
072        if (name.equals("WhatsappVoice")) {
073            name = "whatsapp-voice";
074        }
075        type = ChannelType.fromString(name);
076    }
077
078    /**
079     * This method makes {@link #getType()} return {@code null}; effectively
080     * the opposite of {@linkplain #setTypeField()}. This is useful for some API calls
081     * where the type information should be omitted from the generated JSON.
082     *
083     * @since 8.4.0
084     * @see #setTypeField()
085     */
086    public void removeTypeField() {
087        type = null;
088    }
089
090    /**
091     * Finds the corresponding subclass of Channel based on the enum's value.
092     *
093     * @param type The channel type as an enum.
094     *
095     * @return The appropriate concrete Channel class, or {@code null} if there isn't one.
096     * @since 8.4.0
097     */
098    public static Class<? extends Channel> getConcreteClass(ChannelType type) {
099        if (type == null) return null;
100        switch (type) {
101            default: return null;
102            case MESSENGER: return Messenger.class;
103            case MMS: return Mms.class;
104            case PHONE: return Pstn.class;
105            case SIP: return Sip.class;
106            case SMS: return Sms.class;
107            case VBC: return Vbc.class;
108            case VIBER: return Viber.class;
109            case WEBSOCKET: return Websocket.class;
110            case WHATSAPP: return Whatsapp.class;
111            case WHATSAPP_VOICE: return WhatsappVoice.class;
112        }
113    }
114}