/*
 * 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.rest;

import java.util.Collection;
import org.apache.guacamole.GuacamoleClientException;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleResourceNotFoundException;
import org.apache.guacamole.GuacamoleSecurityException;
import org.apache.guacamole.form.Field;
import org.apache.guacamole.language.Translatable;
import org.apache.guacamole.language.TranslatableMessage;
import org.apache.guacamole.net.auth.credentials.GuacamoleCredentialsException;
import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
import org.apache.guacamole.tunnel.GuacamoleStreamException;

/**
 * Describes an error that occurred within a REST endpoint.
 */
public class APIError {

    /**
     * The human-readable error message.
     */
    private final String message;

    /**
     * A translatable message representing the error that occurred.
     */
    private final TranslatableMessage translatableMessage;

    /**
     * The associated Guacamole protocol status code.
     */
    private final Integer statusCode;

    /**
     * All expected request parameters, if any, as a collection of fields.
     */
    private final Collection<Field> expected;

    /**
     * The type of error that occurred.
     */
    private final Type type;

    /**
     * All possible types of REST API errors.
     */
    public enum Type {

        /**
         * The requested operation could not be performed because the request
         * itself was malformed.
         */
        BAD_REQUEST,

        /**
         * The credentials provided were invalid.
         */
        INVALID_CREDENTIALS,

        /**
         * The credentials provided were not necessarily invalid, but were not
         * sufficient to determine validity.
         */
        INSUFFICIENT_CREDENTIALS,

        /**
         * An internal server error has occurred.
         */
        INTERNAL_ERROR,

        /**
         * An object related to the request does not exist.
         */
        NOT_FOUND,

        /**
         * Permission was denied to perform the requested operation.
         */
        PERMISSION_DENIED,

        /**
         * An error occurred within an intercepted stream, terminating that
         * stream. The Guacamole protocol status code of that error can be
         * retrieved with getStatusCode().
         */
        STREAM_ERROR;

        /**
         * Returns the REST API error type which corresponds to the type of the
         * given exception.
         *
         * @param exception
         *     The exception to use to derive the API error type.
         *
         * @return
         *     The API error type which corresponds to the type of the given
         *     exception.
         */
        public static Type fromGuacamoleException(GuacamoleException exception) {

            // Additional credentials are needed
            if (exception instanceof GuacamoleInsufficientCredentialsException)
                return INSUFFICIENT_CREDENTIALS;

            // The provided credentials are wrong
            if (exception instanceof GuacamoleInvalidCredentialsException)
                return INVALID_CREDENTIALS;

            // Generic permission denied
            if (exception instanceof GuacamoleSecurityException)
                return PERMISSION_DENIED;

            // Arbitrary resource not found
            if (exception instanceof GuacamoleResourceNotFoundException)
                return NOT_FOUND;

            // Arbitrary bad requests
            if (exception instanceof GuacamoleClientException)
                return BAD_REQUEST;

            // Errors from intercepted streams
            if (exception instanceof GuacamoleStreamException)
                return STREAM_ERROR;

            // All other errors
            return INTERNAL_ERROR;

        }

    }

    /**
     * Creates a new APIError which exposes the details of the given
     * GuacamoleException. If the given GuacamoleException implements
     * Translatable, then its translation string and values will be exposed as
     * well.
     *
     * @param exception
     *     The GuacamoleException from which the details of the new APIError
     *     should be derived.
     */
    public APIError(GuacamoleException exception) {

        // Build base REST service error
        this.type = Type.fromGuacamoleException(exception);
        this.message = exception.getMessage();

        // Add expected credentials if applicable
        if (exception instanceof GuacamoleCredentialsException) {
            GuacamoleCredentialsException credentialsException = (GuacamoleCredentialsException) exception;
            this.expected = credentialsException.getCredentialsInfo().getFields();
        }
        else
            this.expected = null;

        // Add stream status code if applicable
        if (exception instanceof GuacamoleStreamException) {
            GuacamoleStreamException streamException = (GuacamoleStreamException) exception;
            this.statusCode = streamException.getStatus().getGuacamoleStatusCode();
        }
        else
            this.statusCode = null;

        // Pull translatable message and values if available
        if (exception instanceof Translatable) {
            Translatable translatable = (Translatable) exception;
            this.translatableMessage = translatable.getTranslatableMessage();
        }
        else
            this.translatableMessage = new TranslatableMessage(this.message);

    }

    /**
     * Returns the type of error that occurred.
     *
     * @return
     *     The type of error that occurred.
     */
    public Type getType() {
        return type;
    }

    /**
     * Returns the Guacamole protocol status code associated with the error
     * that occurred. This is only valid for errors of type STREAM_ERROR.
     *
     * @return
     *     The Guacamole protocol status code associated with the error that
     *     occurred. If the error is not of type STREAM_ERROR, this will be
     *     null.
     */
    public Integer getStatusCode() {
        return statusCode;
    }

    /**
     * Returns a collection of all required parameters, where each parameter is
     * represented by a field.
     *
     * @return
     *     A collection of all required parameters.
     */
    public Collection<Field> getExpected() {
        return expected;
    }

    /**
     * Returns a human-readable error message describing the error that
     * occurred.
     *
     * @return
     *     A human-readable error message.
     */
    public String getMessage() {
        return message;
    }

    /**
     * Returns a translatable message describing the error that occurred. If no
     * translatable message is associated with the error, this will be null.
     *
     * @return
     *     A translatable message describing the error that occurred, or null
     *     if there is no such message defined.
     */
    public TranslatableMessage getTranslatableMessage() {
        return translatableMessage;
    }

}
