// 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.vdl.NativeTypes.Converter;
import io.v.v23.vdl.Types;
import io.v.v23.vdl.VdlAny;
import io.v.v23.vdl.VdlType;
import io.v.v23.vdl.VdlValue;
import io.v.v23.vdl.WireError;
import io.v.v23.vdl.WireRetryCode;
import io.v.v23.verror.VException.ActionCode;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

/**
 * Converts {@code VException} to its VDL wire type and vice-versa.
 */
public final class VExceptionVdlConverter extends Converter {
    public static final VExceptionVdlConverter INSTANCE = new VExceptionVdlConverter();

    private VExceptionVdlConverter() {
        super(WireError.class);
    }

    private WireRetryCode actionCodeToWire(ActionCode code) {
        switch (code) {
            case NO_RETRY: return WireRetryCode.NoRetry;
            case RETRY_CONNECTION: return WireRetryCode.RetryConnection;
            case RETRY_REFETCH: return WireRetryCode.RetryRefetch;
            case RETRY_BACKOFF: return WireRetryCode.RetryBackoff;
            default: return WireRetryCode.NoRetry;
        }
    }

    @Override
    public WireError vdlValueFromNative(Object nativeValue) {
        assertInstanceOf(nativeValue, VException.class);
        VException e = (VException) nativeValue;
        List<VdlAny> paramVals = new ArrayList<VdlAny>();
        Serializable[] params = e.getParams();
        VdlType[] paramTypes = e.getParamTypes();
        for (int i = 0; i < params.length; ++i) {
            if (paramTypes[i] == null) {
                continue;  // dropping the param.
            }
            paramVals.add(new VdlAny(paramTypes[i], params[i]));
        }
        return new WireError(e.getID(), actionCodeToWire(e.getAction()), e.getMessage(), paramVals);
    }

    @Override
    public Object nativeFromVdlValue(VdlValue value) {
        assertInstanceOf(value, WireError.class);
        WireError error = (WireError) value;
        VException.IDAction idAction = new VException.IDAction(error.getId(),
                VException.ActionCode.fromValue(error.getRetryCode().ordinal()));

        List<VdlAny> paramVals = error.getParamList();
        Serializable[] params = new Serializable[paramVals.size()];
        VdlType[] paramTypes = new VdlType[paramVals.size()];
        for (int i = 0; i < paramVals.size(); ++i) {
            VdlAny paramVal = paramVals.get(i);
            params[i] = paramVal.getElem();
            paramTypes[i] = paramVal.getElemType();
        }
        VException v = new VException(idAction, error.getMsg(), params, paramTypes);
        // See if a subclass can handle further conversion.
        String path = classPath(v.getID());
        Class<?> c = Types.loadClassForVdlName(path);
        if (c == null) {
            c = Types.loadClassForVdlName(path + "Exception");
        }
        if (c != null) {
            try {
                Constructor constructor = c.getDeclaredConstructor(VException.class);
                if (!constructor.isAccessible()) {
                    constructor.setAccessible(true);
                }
                return constructor.newInstance(v);
            } catch (Exception e) {}
        }
        return v;
    }

    private static String classPath(String errId) {
        int idx = errId.lastIndexOf(".");
        if (idx < 0) {
            return errId;
        }
        String errName = errId.substring(idx + 1);
        errName = Character.toUpperCase(errName.charAt(0)) + errName.substring(1);
        return errId.substring(0, idx) + "/" + errName;
    }
}
