/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Room & Board
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.smartystreets.spring;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;

@Service
@Primary
public class SmartyStreetsAPI {

    private static final String AUTH_ID_KEY = "auth-id";
    private static final String AUTH_TOKEN_KEY = "auth-token";

    @Value("${smartystreets.api.uri}")
    String apiUri;
    @Value("${smartystreets.api.path.streetaddress}")
    String streetAddressPath;
    @Value("${smartystreets.api.path.zipcode}")
    String zipCodePath;

    @Value("${smartystreets.api.token}")
    String apiToken;
    @Value("${smartystreets.api.authid}")
    String authId;

    public ZipCodeResponse[] zipCode(String zipCode, String city, String state, String inputId) {

        URI uri = createURI(zipCodePath);

        HttpEntity<ZipCodeResponse[]> response = new RestTemplate()
                .postForEntity(uri, new ZipCodeRequest[]{ new ZipCodeRequest(city, state, zipCode, inputId) }, ZipCodeResponse[].class);

        return response.getBody();
    }

    public AddressResponse[] streetAddress(Address address) {

        URI uri = createURI(streetAddressPath);

        return new RestTemplate().postForObject(uri, new Address[]{address}, AddressResponse[].class);
    }

    private URI createURI(String path) {

        return UriComponentsBuilder.fromUriString(apiUri)
                .path(path)
                .queryParam(AUTH_ID_KEY, authId)
                .queryParam(AUTH_TOKEN_KEY, apiToken)
                .build()
                .toUri();
    }

}
@@ -1171,16 +1171,86 @@
 pring;%0A%0A
+import java.net.URI;%0Aimport java.util.HashMap;%0Aimport java.util.Map;%0A%0A
 import o
@@ -1561,30 +1561,8 @@
 r;%0A%0A
-import java.net.URI;%0A%0A
 @Ser
@@ -1727,16 +1727,94 @@
 -token%22;
+%0A    private static final String INCLUDE_INVALID_HEADER = %22x-include-invalid%22;
 %0A%0A    @V
@@ -2280,32 +2280,136 @@
 (zipCodePath);%0A%0A
+        RestTemplate restTemplate = new RestTemplate();%0A        setIncludeInvalidHeader(restTemplate);%0A%0A
         HttpEnti
@@ -2437,29 +2437,25 @@
  response = 
-new R
+r
 estTemplate(
@@ -2453,35 +2453,16 @@
 Template
-()%0A                
 .postFor
@@ -2741,107 +2741,462 @@
     
-return new RestTemplate().postForObject(uri, new Address%5B%5D%7Baddress%7D, AddressResponse%5B%5D.class);%0A    
+RestTemplate restTemplate = new RestTemplate();%0A        setIncludeInvalidHeader(restTemplate);%0A        %0A        return restTemplate.postForObject(uri, new Address%5B%5D%7Baddress%7D, AddressResponse%5B%5D.class);%0A    %7D%0A%0A%09private void setIncludeInvalidHeader(RestTemplate restTemplate) %7B%0A%09%09%0A%09%09Map%3CString, ? super Object%3E headers = new HashMap%3C%3E();%0A        headers.put(INCLUDE_INVALID_HEADER, true);%0A        restTemplate.headForHeaders(%22x-include-invalid%22, headers);%0A%09
 %7D%0A%0A 
@@ -3481,11 +3481,16 @@
 );%0A    %7D
+%0A    
 %0A%0A%7D

Include invalid header