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.voice.ncco;
017
018import com.fasterxml.jackson.annotation.JsonProperty;
019import com.vonage.client.JsonableBaseObject;
020import com.vonage.client.voice.EndpointType;
021import com.vonage.client.voice.SipHeader;
022import java.net.URI;
023import java.util.LinkedHashMap;
024import java.util.Map;
025
026/**
027 * Represents a SIP endpoint used in a {@link ConnectAction}. See
028 * <a href=https://developer.vonage.com/voice/voice-api/ncco-reference#sip-endpoint>the documentation</a>
029 * for an example.
030 */
031public class SipEndpoint extends JsonableBaseObject implements Endpoint {
032    private final URI uri;
033    private final Map<String, ?> headers;
034    private final Map<SipHeader, String> standardHeaders;
035
036    private SipEndpoint(Builder builder) {
037        uri = builder.uri;
038        headers = builder.headers;
039        standardHeaders = builder.standardHeaders;
040    }
041
042    @Override
043    public String getType() {
044        return EndpointType.SIP.toString();
045    }
046
047    /**
048     * URI of the SIP endpoint.
049     *
050     * @return The URI.
051     */
052    @JsonProperty("uri")
053    public URI getUri() {
054        return uri;
055    }
056
057    /**
058     * Defines custom headers to be sent as part of the SIP INVITE request.
059     * All keys will be prepended with the {@code X-} prefix.
060     *
061     * @return The custom headers as a Map, or {@code null} if unspecified.
062     */
063    @JsonProperty("headers")
064    public Map<String, ?> getHeaders() {
065        return headers;
066    }
067
068    /**
069     * Headers that are RFC standards, i.e. not prepended with {@code X-}.
070     *
071     * @return The standard headers, or {@code null} if unspecified.
072     * @since 8.9.0
073     */
074    @JsonProperty("standardHeaders")
075    public Map<SipHeader, String> getStandardHeaders() {
076        return standardHeaders;
077    }
078
079    /**
080     * Entry point for constructing an instance of this class.
081     *
082     * @param uri The SIP URI as a string.
083     *
084     * @return A new Builder.
085     */
086    public static Builder builder(String uri) {
087        return new Builder().uri(uri);
088    }
089
090    /**
091     * Entry point for constructing an instance of this class.
092     *
093     * @param uri The SIP URI.
094     *
095     * @return A new Builder.
096     */
097    public static Builder builder(URI uri) {
098        return new Builder().uri(uri);
099    }
100
101    public static class Builder {
102        private URI uri;
103        private Map<String, ?> headers;
104        private Map<SipHeader, String> standardHeaders;
105
106        private Builder() {}
107
108        private Builder addStandardHeader(SipHeader key, String value) {
109            if (standardHeaders == null) {
110                standardHeaders = new LinkedHashMap<>(2);
111            }
112            standardHeaders.put(key, value);
113            return this;
114        }
115
116        /**
117         * Sets the URI.
118         *
119         * @param uri The URI.
120         * @return This builder.
121         */
122        public Builder uri(URI uri) {
123            this.uri = uri;
124            return this;
125        }
126
127        /**
128         * Sets the URI.
129         *
130         * @param uri The URI as a string.
131         * @return This builder.
132         */
133        public Builder uri(String uri) {
134            return uri(URI.create(uri));
135        }
136
137        /**
138         * Sets the custom headers, which will be prepended with {@code X-} by Vonage.
139         *
140         * @param headers The custom headers as a Map.
141         * @return This builder.
142         */
143        public Builder headers(Map<String, ?> headers) {
144            this.headers = headers;
145            return this;
146        }
147
148        /**
149         * (OPTIONAL) The User-to-User header, as per RFC 7433.
150         *
151         * @param value Value of the {@code User-to-User} header as string.
152         *
153         * @return This builder.
154         * @since 8.9.0
155         */
156        public Builder userToUserHeader(String value) {
157            return addStandardHeader(SipHeader.USER_TO_USER, value);
158        }
159
160        /**
161         * Builds the SIP endpoint.
162         *
163         * @return A new SipEndpoint with this builder's properties.
164         */
165        public SipEndpoint build() {
166            return new SipEndpoint(this);
167        }
168    }
169}