{{>licenseInfo}}

package {{invokerPackage}}.auth;

import {{invokerPackage}}.Pair;
import {{invokerPackage}}.ApiException;

import java.io.ByteArrayInputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.List;

import com.amazonaws.DefaultRequest;
import com.amazonaws.auth.AWS4Signer;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AnonymousAWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.http.HttpMethodName;

import okio.Buffer;

{{>generatedAnnotation}}
public class AWS4Auth implements Authentication {

  private AWSCredentials credentials;
  private String region;
  private String service;

  public AWS4Auth() {
    this.credentials = new AnonymousAWSCredentials();
  }

  public void setCredentials(String accessKey, String secretKey) {
    this.credentials = new BasicAWSCredentials(accessKey, secretKey);
  }

  public void setRegion(String region) {
    this.region = region;
  }

  public void setService(String service) {
    this.service = service;
  }

  @Override
  public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams,
      String payload, String method, URI uri) throws ApiException {

    DefaultRequest<String> signableRequest = new DefaultRequest<>(this.service);

    signableRequest.setContent(new ByteArrayInputStream(payload.getBytes()));

    signableRequest.setHttpMethod(HttpMethodName.valueOf(method));
    URI targetUri = null;
    try {
      targetUri = new URI(uri.getScheme(), "", uri.getHost(), uri.getPort(), "", "", "");
    } catch (URISyntaxException e) {
      return;
    }
    signableRequest.setEndpoint(targetUri);
    signableRequest.setResourcePath(uri.getPath());

    AWS4Signer signer = new AWS4Signer(false);
    signer.setServiceName(this.service);
    signer.setRegionName(this.region);
    signer.sign(signableRequest, credentials);

    headerParams.putAll(signableRequest.getHeaders());
  }
}
