/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.guacamole.language;

import org.apache.guacamole.GuacamoleClientBadTypeException;

/**
 * A {@link GuacamoleClientBadTypeException} whose associated message is
 * translatable and can be passed through an arbitrary translation service,
 * producing a human-readable message in the user's native language.
 */
public class TranslatableGuacamoleClientBadTypeException extends GuacamoleClientBadTypeException implements Translatable {

    /**
     * A translatable, human-readable description of the exception that
     * occurred.
     */
    private final TranslatableMessage translatableMessage;

    /**
     * Creates a new TranslatableGuacamoleClientBadTypeException with the given
     * message and cause. The message must be provided in both non-translatable
     * (readable as-written) and translatable forms.
     *
     * @param message
     *     A human-readable description of the exception that occurred. This
     *     message should be readable on its own and as-written, without
     *     requiring a translation service.
     *
     * @param translatableMessage
     *     A translatable, human-readable description of the exception that
     *     occurred.
     *
     * @param cause
     *     The cause of this exception.
     */
    public TranslatableGuacamoleClientBadTypeException(String message, TranslatableMessage translatableMessage, Throwable cause) {
        super(message, cause);
        this.translatableMessage = translatableMessage;
    }

    /**
     * Creates a new TranslatableGuacamoleClientBadTypeException with the given
     * message. The message must be provided in both non-translatable (readable
     * as-written) and translatable forms.
     *
     * @param message
     *     A human-readable description of the exception that occurred. This
     *     message should be readable on its own and as-written, without
     *     requiring a translation service.
     *
     * @param translatableMessage
     *     A translatable, human-readable description of the exception that
     *     occurred.
     */
    public TranslatableGuacamoleClientBadTypeException(String message, TranslatableMessage translatableMessage) {
        super(message);
        this.translatableMessage = translatableMessage;
    }

    /**
     * Creates a new TranslatableGuacamoleClientBadTypeException with the given
     * message and cause. The message must be provided in both non-translatable
     * (readable as-written) and translatable forms.
     *
     * @param message
     *     A human-readable description of the exception that occurred. This
     *     message should be readable on its own and as-written, without
     *     requiring a translation service.
     *
     * @param key
     *     The arbitrary key which can be used to look up the message to be
     *     displayed in the user's native language.
     *
     * @param cause
     *     The cause of this exception.
     */
    public TranslatableGuacamoleClientBadTypeException(String message, String key, Throwable cause) {
        this(message, new TranslatableMessage(key), cause);
    }

    /**
     * Creates a new TranslatableGuacamoleClientBadTypeException with the given
     * message. The message must be provided in both non-translatable (readable
     * as-written) and translatable forms.
     *
     * @param message
     *     A human-readable description of the exception that occurred. This
     *     message should be readable on its own and as-written, without
     *     requiring a translation service.
     *
     * @param key
     *     The arbitrary key which can be used to look up the message to be
     *     displayed in the user's native language.
     */
    public TranslatableGuacamoleClientBadTypeException(String message, String key) {
        this(message, new TranslatableMessage(key));
    }

    @Override
    public TranslatableMessage getTranslatableMessage() {
        return translatableMessage;
    }

}
