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.verify;
017
018import com.vonage.client.QueryParamsRequest;
019import com.vonage.client.common.E164;
020import java.util.LinkedHashMap;
021import java.util.Locale;
022import java.util.Map;
023
024/**
025 * Base request class for {@link VerifyRequest} and {@link Psd2Request}.
026 * @since 5.5.0
027 */
028public abstract class BaseRequest implements QueryParamsRequest {
029    private final String number, country;
030    private final Integer length, pinExpiry, nextEventWait;
031    private final Locale locale;
032
033    protected BaseRequest(String number, Integer length, Locale locale, String country, Integer pinExpiry, Integer nextEventWait) {
034        this.number = new E164(number).toString();
035        this.locale = locale;
036        this.country = country;
037        if ((this.length = length) != null && (length != 4 && length != 6)) {
038            throw new IllegalArgumentException("code_length must be 4 or 6.");
039        }
040        if ((this.pinExpiry = pinExpiry) != null && (pinExpiry < 60 || pinExpiry > 3600)) {
041            throw new IllegalArgumentException("pin_expiry '"+pinExpiry+"' is out of bounds.");
042        }
043        if ((this.nextEventWait = nextEventWait) != null && (nextEventWait < 60 || nextEventWait > 900)) {
044            throw new IllegalArgumentException("next_event_wait '"+nextEventWait+"' is out of bounds.");
045        }
046    }
047
048    /**
049     * @return the recipient's phone number provided in the constructor, in
050     * <a href="https://en.wikipedia.org/wiki/E.164">E.164</a> format.
051     */
052    public String getNumber() {
053        return number;
054    }
055
056    /**
057     * @return the length of the verification code to be sent to the user, specified in some {@link VerifyRequest}
058     * constructors. {@code -1} indicates the default length will be used.
059     */
060    public Integer getLength() {
061        return length;
062    }
063
064    /**
065     * @return the default locale used for verification. If this value is {@code null}, the locale will be determined
066     * from the country code included in {@code number}
067     */
068    public Locale getLocale() {
069        return locale;
070    }
071
072    /**
073     * @return the default locale used for verification in snake case.
074     * Ex: {@code en-gb}
075     * If this value is {@code null}, the locale will be determined
076     * from the country code included in {@code number}
077     */
078    public String getDashedLocale() {
079        if (locale != null) {
080           return locale.toLanguageTag().toLowerCase();
081        }
082        else return null;
083    }
084
085    /**
086     * The country for the destination phone number.
087     *
088     * @return a String containing a 2-character country code
089     */
090    public String getCountry() {
091        return country;
092    }
093
094    /**
095     * How long the generated verification code is valid for, in seconds. When you specify both {@code pin_expiry}
096     * and {@code next_event_wait} then {@code pin_expiry} must be an integer multiple of
097     * {@code next_event_wait}, otherwise {@code pin_expiry} will be equal to {@code next_event_wait}.
098     *
099     * @return An Integer between {@code 60} and {@code 3600}, or {@code null}.
100     */
101    public Integer getPinExpiry() {
102        return pinExpiry;
103    }
104
105    /**
106     * The wait time between attempts to deliver the PIN.
107     *
108     * @return An Integer between {@code 60} and {@code 900}, or {@code null}.
109     */
110    public Integer getNextEventWait() {
111        return nextEventWait;
112    }
113
114    @Override
115    public String toString() {
116        return  "number='" + number + '\'' +
117                ", length=" + length +
118                ", locale=" + locale +
119                ", country='" + country + '\'' +
120                ", pinExpiry=" + pinExpiry +
121                ", nextEventWait=" + nextEventWait;
122    }
123
124    @Override
125    public Map<String, String> makeParams() {
126        Map<String, String> params = new LinkedHashMap<>();
127        if (number != null) {
128            params.put("number", number);
129        }
130        if (length != null && length > 0) {
131            params.put("code_length", String.valueOf(length));
132        }
133        if (locale != null) {
134            params.put("lg", getDashedLocale());
135        }
136        if (country != null) {
137            params.put("country", country);
138        }
139        if (pinExpiry != null) {
140            params.put("pin_expiry", String.valueOf(pinExpiry));
141        }
142        if (nextEventWait != null) {
143            params.put("next_event_wait", String.valueOf(nextEventWait));
144        }
145        return params;
146    }
147}