// Copyright 2011 Google Inc. All Rights Reserved.
//
// 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.enterprise.adaptor;

import java.text.MessageFormat;
import java.util.*;

/**
 * Enum for all translation keys. All user-visible messages should exist in our
 * resource bundle and have its key here.
 */
enum Translation {
  AUTHN_RETRY,
  AUTHN_UNKNOWN_SESSION,
  AUTHN_NOT_STARTED,
  AUTHZ_BAD_QUERY_NO_RESOURCE,
  AUTHZ_BAD_QUERY_NO_SUBJECT,
  AUTHZ_BAD_QUERY_NOT_SAME_USER,
  HTTP_BAD_REQUEST_INVALID_JSON,
  HTTP_BAD_REQUEST_ERROR_DECODING,
  HTTP_BAD_REQUEST_SECURITY_ERROR,
  HTTP_FORBIDDEN,
  HTTP_FORBIDDEN_AUTHN_FAILURE,
  HTTP_FORBIDDEN_SECMGR,
  HTTP_NOT_FOUND,
  HTTP_BAD_METHOD,
  HTTP_CONFLICT_INVALID_HEADER,
  HTTP_INTERNAL_ERROR,
  STATS_VERSION_UNKNOWN,
  STATUS_CRAWLING,
  STATUS_CRAWLING_NO_ACCESSES_IN_PAST_DAY,
  STATUS_ERROR_RATE,
  STATUS_ERROR_RATE_RATE,
  STATUS_FEED,
  STATUS_FEED_INTERRUPTED,
  ;

  /**
   * @throws java.util.MissingResourceException if it could not find a string
   *   for the default locale
   */
  @Override
  public String toString() {
    return toString(Locale.getDefault());
  }

  /**
   * @throws java.util.MissingResourceException if it could not find a string
   *   for the provided {@code locale}
   */
  public String toString(Locale locale) {
    String localeClassStr = "com.google.enterprise.adaptor.TranslationStrings";
    return ResourceBundle.getBundle(localeClassStr, locale)
        .getString(name());
  }

  /**
   * @throws java.util.MissingResourceException if it could not find a string
   *   for the default locale
   */
  public String toString(Object... params) {
    return toString(Locale.getDefault(), params);
  }

  /**
   * @throws java.util.MissingResourceException if it could not find a string
   *   for the provided {@code locale}
   */
  public String toString(Locale locale, Object... params) {
    String translation = toString(locale);
    return new MessageFormat(translation, locale)
        .format(params, new StringBuffer(), null).toString();
  }
}
