package ru.yandex.autodoc.wmtools.errors.view;

import ru.yandex.autodoc.common.out.json.JsonArrayWriter;
import ru.yandex.autodoc.common.out.json.JsonConvertableUtils;
import ru.yandex.autodoc.common.out.json.builder.ContainerBuilder;
import ru.yandex.autodoc.common.out.json.builder.JsonArrayBuilder;
import ru.yandex.autodoc.common.out.json.builder.JsonValueBuilder;
import ru.yandex.wmtools.common.error.CodeErrorInfo;
import ru.yandex.wmtools.common.error.ExtraTagInfo;

import java.util.Collection;

/**
 * @author avhaliullin
 */
public class AbstractErrorWrapper extends CodeErrorInfo implements WrappedError {
    private final String message;
    private final String userText;
    private final Throwable throwable;
    private final Collection<ExtraTagInfo> params;

    public AbstractErrorWrapper(Object code, Integer id, String message, String userText, Throwable throwable, Collection<ExtraTagInfo> extraParams) {
        super(code, id, message, userText, throwable, extraParams);
        this.message = message;
        this.userText = userText;
        this.throwable = throwable;
        this.params = extraParams;
    }

    @Override
    public void toJson(StringBuilder storage) {
        writeValue(JsonConvertableUtils.createValueBuilder(storage));
    }

    @Override
    public <C extends ContainerBuilder> C writeValue(JsonValueBuilder<C> builder) {
        String text = userText == null ? null : parseUserText(userText, params);
        String exception = throwable.getClass().getName() + ": " + throwable.getMessage();
        return builder
                .valueObject()
                .keyValueObjectAsString("code", data)
                .keyValueBoolean("isInternal", true)
                .keyValue("message", message)
                .keyValue("userText", text)
                .key("params").valueArray(new JsonArrayWriter() {
                    @Override
                    public <C extends ContainerBuilder> JsonArrayBuilder<C> writeArray(JsonArrayBuilder<C> builder) {
                        if (params != null) {
                            for (ExtraTagInfo param : params) {
                                builder = builder.element()
                                        .valueObject()
                                        .keyValue("name", param.getName())
                                        .keyValue("value", param.getValue())
                                        .endObject();
                            }
                        }
                        return builder;
                    }
                })
                .keyValue("exception", exception)
                .endObject();
    }
}

