// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.v23.verror;

import io.v.v23.context.VContext;
import io.v.v23.i18n.Language;
import io.v.v23.vdl.Types;
import io.v.v23.vdl.VdlType;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Captures errors that occurred in the Vanadium environment, both in the core Vanadium code as
 * well as the user-defined clients and servers.
 * <p>
 * Each {@link VException} has an identifier associated with it that uniquely represents an error.
 * Two {@link VException}s are equal iff their identifiers are equal, regardless of the associated
 * messages.  This allows the user to throw {@link VException}s with different messages (e.g.,
 * multiple languages) yet have the caller interpret them all as the same error.
 * <p>
 * To define a new error identifier, for example {@code "someNewError"}, client code is
 * expected to declare a variable like this:
 * <p><blockquote><pre>
 * VException.IDAction someNewError = VException.register(
 *         "my/package/name.someNewError",
 *         VException.ActionCode.NO_RETRY,
 *         "{1} {2} English text for new error");
 * </pre></blockquote><p>
 * Error identifier strings should start with the package path to ensure uniqueness.  Note that the
 * package paths are separated with {@code "/"} delimiter; this is a chosen convention to make
 * the error uniquely identifiable across various programming languages.
 * <p>
 * The purpose of an {@link ActionCode} is so clients not familiar with an error can retry
 * appropriately.
 * <p>
 * Errors are registered with their English text, but the text for other languages can subsequently
 * be added to the default {@link io.v.v23.i18n.Catalog} using the returned error identifier.
 * <p>
 * {@link VException}s are given parameters when created.  Conventionally, the first parameter
 * is the name of the component (typically server or binary name), and the second is the name of the
 * operation (such as an RPC or sub-command) that encountered the error.  Other parameters typically
 * identify the object(s) on which the error occurred.  This convention is normally applied by
 * {@link #VException(IDAction,VContext,Serializable...)}, which fetches the language, component name
 * and operation name from the current context:
 * <p><blockquote><pre>
 * VException e = new VException(someNewError, ctx, "object_on_which_error_occurred");
 * </pre></blockquote><p>
 * The {@link #VException(IDAction,String,String,String,Serializable...)} constructor can be used
 * to specify these things explicitly:
 * <p><blockquote><pre>
 * VException e = new VException(
 *         someNewError, "en", "my_component", "op_name", "procedure_name", "object_name");
 * </pre></blockquote><p>
 * If the language, component and/or operation name are unknown, use an empty string.
 * <p>
 * Because of the convention for the first two parameters, error messages in the catalog typically
 * look like this (at least for left-to-right languages):
 * <p><blockquote><pre>
 *      {1} {2} The new error {_}
 * </pre></blockquote><p>
 * Tokens {@code {1}}, {@code {2}}, etc.  refer to the first and second positional
 * parameters respectively, while {@code {_}} is replaced by the positional parameters not
 * explicitly referred to elsewhere in the message.  Thus, given the parameters above, this would
 * lead to the output:
 * <p><blockquote><pre>
 *      my_component op_name The new error object_name
 * </pre></blockquote><p>
 * If a substring is of the form {@code {:<number>}, {<number>:}, {:<number>:},
 * {:_}, {_:}, or {:_:}} and the corresponding parameters are not the empty string, the parameter is
 * preceded by {@code ": "} or followed by {@code ":"} or both, respectively.
 */
public class VException extends Exception {
    private static final long serialVersionUID = 1L;
    private static VContext defaultContext = null;
    private static final ReadWriteLock lock = new ReentrantReadWriteLock();

    /**
     * Action expected to be performed by a typical client receiving an error that perhaps
     * it does not understand.
     */
    public static enum ActionCode {
        /**
         * Do not retry.
         */
        NO_RETRY         (0),
        /**
         * Renew high-level connection/context.
         */
        RETRY_CONNECTION (1),
        /**
         * Refetch and retry (e.g., out of date HTTP ETag).
         */
        RETRY_REFETCH    (2),
        /**
         * Backoff and retry a finite number of times.
         */
        RETRY_BACKOFF    (3);

        /**
         * Returns an {@link ActionCode} corresponding to the given integer value.
         */
        public static ActionCode fromValue(int value) {
            switch (value) {
                case 0: return NO_RETRY;
                case 1: return RETRY_CONNECTION;
                case 2: return RETRY_REFETCH;
                case 3: return RETRY_BACKOFF;
                default: return NO_RETRY;
            }
        }

        private final int value;

        private ActionCode(int value) {
            this.value = value;
        }

        /**
         * Returns the integer value corresponding to this {@link ActionCode}.
         */
        public int getValue() { return this.value; }
    }

    /**
     * A pair of (error identifier, {@link ActionCode}).  The error identifier allows stable error
     * checking across different error messages and different address spaces.
     * <p>
     * By convention the format for the identifier is {@code "PKGPATH.NAME"} - e.g. {@code errIDFoo}
     * defined in the {@code io.v.v23.verror} package has id {@code io.v.v23.verror.errIDFoo}.
     * It is unwise ever to create two {@link IDAction}s that associate different
     * {@link ActionCode}s with the same id.
    */
    public static class IDAction {
        private final String id;
        private final ActionCode action;

        public IDAction(String id, ActionCode action) {
            this.id = id == null ? "" : id;
            this.action = action;
        }

        public String getID() { return this.id; }

        public ActionCode getAction() { return this.action; }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null) return false;
            if (this.getClass() != obj.getClass()) return false;
            IDAction other = (IDAction) obj;
            if (!this.id.equals(other.id)) return false;
            if (this.action != other.action) return false;
            return true;
        }

        @Override
        public int hashCode() {
            int result = 1;
            int prime = 31;
            result = prime * result + id.hashCode();
            result = prime * result + action.hashCode();
            return result;
        }

        @Override
        public String toString() {
            return String.format("{ID: %s, Action: %s}", this.id, this.action);
        }
    }

    /**
     * Returns an {@link IDAction} with the given identifier and action fields and
     * inserts a message into the default i18n catalog in US English.  Other languages can be
     * added by directly modifying the catalog.
     *
     * @param  id          error identifier
     * @param  action      error action
     * @param  englishText english message associated with the error
     * @return             {@code IDAction} with the given identifier and action fields
     */
    public static IDAction register(String id, ActionCode action, String englishText) {
        Language.getDefaultCatalog().setWithBase("en-US", id, englishText);
        return new IDAction(id, action);
    }

    /**
     * Sets the default context that is used whenever a user passes in a {@code null} context
     * to the {@link VException} constructors.
     *
     * @param ctx default context
     */
    public static void setDefaultContext(VContext ctx) {
        lock.writeLock().lock();
        defaultContext = ctx;
        lock.writeLock().unlock();
    }

    /**
     * Returns a child of the given context that has the provided component name attached to it.
     *
     * @param  base          base context
     * @param  componentName a component name that is to be attached
     */
    public static VContext contextWithComponentName(VContext base, String componentName) {
        return base.withValue(new ComponentNameKey(), componentName);
    }

    private static VException create(IDAction idAction, String language, String componentName,
            String opName, Serializable[] params, VdlType[] paramTypes) {
        if (params == null) {
            params = new Serializable[0];
        }
        if (paramTypes == null) {
            paramTypes = new VdlType[0];
        }
        if (params.length != paramTypes.length) {
            System.err.println(String.format(
                    "Passed different number of types (%s) than parameters (%s) to VException. " +
                    "Some params may be dropped.",
                    Arrays.toString(paramTypes), Arrays.toString(params)));
            int length = params.length <= paramTypes.length ? params.length : paramTypes.length;
            params = Arrays.copyOf(params, length);
            paramTypes = Arrays.copyOf(paramTypes, length);
        }
        // Append componentName and opName to params.
        Serializable[] newParams = new Serializable[params.length + 2];
        VdlType[] newParamTypes = new VdlType[paramTypes.length + 2];
        newParams[0] = componentName;
        newParamTypes[0] = Types.STRING;
        newParams[1] = opName;
        newParamTypes[1] = Types.STRING;
        System.arraycopy(params, 0, newParams, 2, params.length);
        System.arraycopy(paramTypes, 0, newParamTypes, 2, params.length);
        String msg = Language.getDefaultCatalog().format(
                    language, idAction.getID(), (Object[]) newParams);
        return new VException(idAction, msg, newParams, newParamTypes);
    }

    private static String componentNameFromContext(VContext ctx) {
        if (ctx == null) {
            lock.readLock().lock();
            ctx = defaultContext;
            lock.readLock().unlock();
        }
        String componentName = "";
        if (ctx != null) {
            Object value = ctx.value(new ComponentNameKey());
            if (value != null && value instanceof String) {
                componentName = (String) value;
            }
        }
        if (componentName.isEmpty()) {
            componentName = System.getProperty("program.name", "");
        }
        if (componentName.isEmpty()) {
            componentName = System.getProperty("user.name", "");
        }
        return componentName;
    }

    private static String languageFromContext(VContext ctx) {
        if (ctx == null) {
            lock.readLock().lock();
            ctx = defaultContext;
            lock.readLock().unlock();
        }
        String language = "";
        if (ctx != null) {
            language = Language.languageFromContext(ctx);
        }
        if (language.isEmpty()) {
            language = "en-US";
        }
        return language;
    }

    private static Type[] createParamTypes(Serializable[] params) {
        Type[] ret = new Type[params.length];
        for (int i = 0; i < params.length; ++i) {
            ret[i] = params[i] == null ? String.class : params[i].getClass();
        }
        return ret;
    }

    private static VdlType[] convertParamTypes(Type[] types) {
        if (types == null) {
            return null;
        }
        VdlType[] vdlTypes = new VdlType[types.length];
        for (int i = 0; i < types.length; ++i) {
            try {
                vdlTypes[i] = Types.getVdlTypeFromReflect(types[i]);
            } catch (IllegalArgumentException e) {
                System.err.println(String.format(
                        "Couldn't determine VDL type for param reflect type %s.  This param will " +
                        "be dropped if ever VOM-encoded", types[i]));
                vdlTypes[i] = null;
            }
        }
        return vdlTypes;
    }

    private final IDAction id;  // non-null
    private final Serializable[] params;  // non-null
    private final VdlType[] paramTypes;  // non-null, same length as params

    /**
     * Creates a new {@code Errors.UNKNOWN} error in English and empty
     * component/operation names.
     *
     * @param  msg error message
     */
    public VException(String msg) {
        this(Errors.UNKNOWN, (VContext) null, msg);
    }

    /**
     * Same as {@link #VException(IDAction,String,String,String,Serializable...)} but
     * obtains the language, component name, and operation name from the given context.  If the
     * provided context is {@code null}, default values are used.
     */
    public VException(IDAction idAction, VContext ctx, Serializable... params) {
        this(idAction, ctx, params, createParamTypes(params));
    }

    /**
     * Same as {@link #VException(IDAction,VContext,Serializable...)} but explicitly provides the
     * types for all parameters.  This is necessary as parameters may need to be VOM-encoded (to be
     * shipped across the wire), and Java doesn't always have the ability to deduce the right type
     * from the value (e.g., generic parameters like {@code List<String>} or
     * {@code Map<String, Integer>}).
     */
    public VException(IDAction idAction, VContext ctx, Serializable[] params, Type[] paramTypes) {
        // TODO(spetrovic): implement the opName support.
        this(idAction, languageFromContext(ctx), componentNameFromContext(ctx),
                "", params, paramTypes);
    }

    /**
     * Returns an error with the given identifier and an error string in the chosen language.
     * The component and operation name are included the first and second parameters of the error.
     * Other parameters are taken from {@code params}. The parameters are formatted into the message
     * according to the format described in the {@link VException} documentation.
     *
     * @param  idAction      error identifier
     * @param  language      error language, in IETF format
     * @param  componentName error component name
     * @param  opName        error operation name
     * @param  params        error message parameters
     */
    public VException(IDAction idAction, String language, String componentName, String opName,
            Serializable... params) {
        this(idAction, language, componentName, opName, params, createParamTypes(params));
    }

    /**
     * Same as {@link #VException(IDAction,String,String,String,Serializable...)} but
     * explicitly provides the types for all parameters.  This is necessary as parameters may need
     * to be VOM-encoded (to be shipped across the wire), and Java doesn't always have the ability
     * to deduce the right type from the value (e.g., generic parameters like {@code List<String>}
     * or {@code Map<String, Integer>}).
     */
    public VException(IDAction idAction, String language, String componentName, String opName,
            Serializable[] params, Type[] paramTypes) {
        this(create(idAction, language, componentName,
                opName, params, convertParamTypes(paramTypes)));
    }

    VException(IDAction id, String msg, Serializable[] params, VdlType[] paramTypes) {
        super(msg);
        this.id = id;
        this.params = params;
        this.paramTypes = paramTypes;
    }

    private VException(VException other) {
        this(other.id, other.getMessage(), other.params, other.paramTypes);
    }

    /**
     * Returns the error identifier associated with this {@link VException}.
     */
    public String getID() {
        return this.id.getID();
    }

    /**
     * Returns the action associated with this {@link VException}.
     */
    public ActionCode getAction() {
        return this.id.getAction();
    }

    /**
     * Returns true iff the error identifier associated with this {@link VException} is equal to the provided
     * identifier.
     *
     * @param  id the error identifier we're comparing with this error
     */
    public boolean is(String id) {
        return getID().equals(id);
    }

    /**
     * Returns true iff the error identifier associated with this {@link VException} is equal to the provided
     * identifier.
     *
     * @param  idAction the error identifier we're comparing with this error
     */
    public boolean is(IDAction idAction) {
        return is(idAction.getID());
    }

    /**
     * Returns true if this {@link VException} is deeply equal to the provided {@link Object}.
     * Unlike {@link #equals equals}, this method, in addition to comparing identifiers, also
     * compares {@link ActionCode}s and parameters.
     *
     * @param  obj the other object we are testing for equality
     */
    public boolean deepEquals(Object obj) {
        if (!equals(obj)) return false;
        VException other = (VException) obj;
        // equals() has already compared the IDs.
        if (!getAction().equals(other.getAction())) return false;
        if (!Arrays.deepEquals(getParams(), other.getParams())) return false;
        return Arrays.equals(getParamTypes(), other.getParamTypes());
    }

    private static class ComponentNameKey {
        @Override
        public int hashCode() {
            return 0;
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (this.getClass() != obj.getClass()) return false;
        VException other = (VException) obj;
        return this.getID().equals(other.getID());
    }

    @Override
    public int hashCode() {
        return this.id.hashCode();
    }

    Serializable[] getParams() { return this.params; }

    VdlType[] getParamTypes() { return this.paramTypes; }
}
