/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.trace;

import java.lang.management.ManagementFactory;
import java.util.concurrent.atomic.AtomicInteger;
import net.ranides.assira.text.ResolveFormatUtils;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class NSTException extends RuntimeException {

    private static final String EMPTY_TEXT = "";
    
    private static final Object[] EMPTY_ARGS = new Object[0];
    
    private static final AtomicInteger COUNTER = new AtomicInteger(0);
    
    private static final class Li { // NOPMD - lazy init idiom
        
        public static final String VMNAME = ManagementFactory.getRuntimeMXBean().getName();
        
    }
    
    private final String uid;
    private final String pattern;
    private final Object[] arguments;
    
    public NSTException() {
        this(EMPTY_TEXT, EMPTY_ARGS);
    }

    public NSTException(String message) {
        this(message, EMPTY_ARGS);
    }
    
    public NSTException(String message, Object... arguments) {
        this.uid = initUID();
        this.pattern = message;
        this.arguments = arguments;
    }
    
    public NSTException(Throwable cause) {
        this(cause, EMPTY_TEXT, EMPTY_ARGS);
    }

    public NSTException(Throwable cause, String message) {
        this(cause, message, EMPTY_ARGS);
    }
    
    public NSTException(Throwable cause, String message, Object... arguments) {
        super(cause);
        this.uid = initUID();
        this.pattern = message;
        this.arguments = arguments;
    }
    
    public String uid() {
        return uid;
    }
    
    @Override
    public Throwable fillInStackTrace() {
        return this;
    }
    
    @Override
    public String getMessage() {
        return ResolveFormatUtils.vformat(pattern, arguments);
    }

    @Override
    public String getLocalizedMessage() {
        return getMessage();
    }

    @Override
    public String toString() {
        String s = getClass().getName();
        String m = getLocalizedMessage();
        return s + "(" + uid + "): " + m;
    }
    
    private static String initUID() {
        return Li.VMNAME + "@" + COUNTER.incrementAndGet();
    }
}
