/**
 * This code was generated by
 * \ / _    _  _|   _  _
 *  | (_)\/(_)(_|\/| |(/_  v1.0.0
 *       /       /
 */

package com.twilio.rest.api.v2010.account;

import com.twilio.base.Updater;
import com.twilio.exception.ApiConnectionException;
import com.twilio.exception.ApiException;
import com.twilio.exception.RestException;
import com.twilio.http.HttpMethod;
import com.twilio.http.Request;
import com.twilio.http.Response;
import com.twilio.http.TwilioRestClient;
import com.twilio.rest.Domains;

public class AddressUpdater extends Updater<Address> {
    private String pathAccountSid;
    private final String pathSid;
    private String friendlyName;
    private String customerName;
    private String street;
    private String city;
    private String region;
    private String postalCode;
    private Boolean emergencyEnabled;
    private Boolean autoCorrectAddress;

    /**
     * Construct a new AddressUpdater.
     *
     * @param pathSid The unique string that identifies the resource
     */
    public AddressUpdater(final String pathSid) {
        this.pathSid = pathSid;
    }

    /**
     * Construct a new AddressUpdater.
     *
     * @param pathAccountSid The SID of the Account that is responsible for the
     *                       resource to update
     * @param pathSid The unique string that identifies the resource
     */
    public AddressUpdater(final String pathAccountSid,
                          final String pathSid) {
        this.pathAccountSid = pathAccountSid;
        this.pathSid = pathSid;
    }

    /**
     * A descriptive string that you create to describe the address. It can be up to
     * 64 characters long..
     *
     * @param friendlyName A string to describe the resource
     * @return this
     */
    public AddressUpdater setFriendlyName(final String friendlyName) {
        this.friendlyName = friendlyName;
        return this;
    }

    /**
     * The name to associate with the address..
     *
     * @param customerName The name to associate with the address
     * @return this
     */
    public AddressUpdater setCustomerName(final String customerName) {
        this.customerName = customerName;
        return this;
    }

    /**
     * The number and street address of the address..
     *
     * @param street The number and street address of the address
     * @return this
     */
    public AddressUpdater setStreet(final String street) {
        this.street = street;
        return this;
    }

    /**
     * The city of the address..
     *
     * @param city The city of the address
     * @return this
     */
    public AddressUpdater setCity(final String city) {
        this.city = city;
        return this;
    }

    /**
     * The state or region of the address..
     *
     * @param region The state or region of the address
     * @return this
     */
    public AddressUpdater setRegion(final String region) {
        this.region = region;
        return this;
    }

    /**
     * The postal code of the address..
     *
     * @param postalCode The postal code of the address
     * @return this
     */
    public AddressUpdater setPostalCode(final String postalCode) {
        this.postalCode = postalCode;
        return this;
    }

    /**
     * Whether to enable emergency calling on the address. Can be: `true` or
     * `false`..
     *
     * @param emergencyEnabled Whether to enable emergency calling on the address
     * @return this
     */
    public AddressUpdater setEmergencyEnabled(final Boolean emergencyEnabled) {
        this.emergencyEnabled = emergencyEnabled;
        return this;
    }

    /**
     * Whether we should automatically correct the address. Can be: `true` or
     * `false` and the default is `true`. If empty or `true`, we will correct the
     * address you provide if necessary. If `false`, we won't alter the address you
     * provide..
     *
     * @param autoCorrectAddress Whether we should automatically correct the address
     * @return this
     */
    public AddressUpdater setAutoCorrectAddress(final Boolean autoCorrectAddress) {
        this.autoCorrectAddress = autoCorrectAddress;
        return this;
    }

    /**
     * Make the request to the Twilio API to perform the update.
     *
     * @param client TwilioRestClient with which to make the request
     * @return Updated Address
     */
    @Override
    @SuppressWarnings("checkstyle:linelength")
    public Address update(final TwilioRestClient client) {
        this.pathAccountSid = this.pathAccountSid == null ? client.getAccountSid() : this.pathAccountSid;
        Request request = new Request(
            HttpMethod.POST,
            Domains.API.toString(),
            "/2010-04-01/Accounts/" + this.pathAccountSid + "/Addresses/" + this.pathSid + ".json"
        );

        addPostParams(request);
        Response response = client.request(request);

        if (response == null) {
            throw new ApiConnectionException("Address update failed: Unable to connect to server");
        } else if (!TwilioRestClient.SUCCESS.test(response.getStatusCode())) {
            RestException restException = RestException.fromJson(response.getStream(), client.getObjectMapper());
            if (restException == null) {
                throw new ApiException("Server Error, no content");
            }
            throw new ApiException(restException);
        }

        return Address.fromJson(response.getStream(), client.getObjectMapper());
    }

    /**
     * Add the requested post parameters to the Request.
     *
     * @param request Request to add post params to
     */
    private void addPostParams(final Request request) {
        if (friendlyName != null) {
            request.addPostParam("FriendlyName", friendlyName);
        }

        if (customerName != null) {
            request.addPostParam("CustomerName", customerName);
        }

        if (street != null) {
            request.addPostParam("Street", street);
        }

        if (city != null) {
            request.addPostParam("City", city);
        }

        if (region != null) {
            request.addPostParam("Region", region);
        }

        if (postalCode != null) {
            request.addPostParam("PostalCode", postalCode);
        }

        if (emergencyEnabled != null) {
            request.addPostParam("EmergencyEnabled", emergencyEnabled.toString());
        }

        if (autoCorrectAddress != null) {
            request.addPostParam("AutoCorrectAddress", autoCorrectAddress.toString());
        }
    }
}