/**
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package com.google.step2.discovery;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.regex.Pattern;

/**
 * Class that represents a URITemplate. URI templates can occur in two different
 * places: (1) in host-meta documents within a Link-Pattern, and (2) in
 * a site's XRD(S) document. In either case, their purpose is to generate
 * a URI that will point to a user's XRD(S) document. This URI is generated by
 * applying the user's OpenID URL to the template (usually, by replacing the
 * template's '{uri}' placeholder with the OpenID URL.
 */
public class UriTemplate {

  // this pattern should be replaced by a URI without escaping that URI first.
  private static final Pattern URI_NO_ESCAPE =
    Pattern.compile("\\{uri\\}", Pattern.CASE_INSENSITIVE);

  // this pattern should be replaced by the escaped form of a URI.
  private static final Pattern URI_ESCAPE =
    Pattern.compile("\\{%uri\\}", Pattern.CASE_INSENSITIVE);

  // the template (e.g. "http://www.foo.com/openid?uri={%uri}")
  private final String template;

  public UriTemplate(String template) {
    this.template = template.trim();
  }

  public URI map(URI uri) {
    String encodedUri;
    try {
      encodedUri = URLEncoder.encode(uri.toString(), "UTF-8");
    } catch (UnsupportedEncodingException e) {
      throw new IllegalArgumentException("could not encode URI "
          + uri.toASCIIString(), e);
    }

    String uriMap = template;
    uriMap = URI_ESCAPE.matcher(uriMap).replaceAll(encodedUri);
    uriMap = URI_NO_ESCAPE.matcher(uriMap).replaceAll(uri.toString());

    return URI.create(uriMap);
  }
}
