/* This file was generated by SableCC's ObjectMacro. */

package org.sablecc.objectmacro.errormessage;

import java.util.*;

public class MInternalError
        extends Macro {

    private DSeparator StackTraceSeparator;

    private DBeforeFirst StackTraceBeforeFirst;

    private DAfterLast StackTraceAfterLast;

    private DNone StackTraceNone;

    final List<String> list_StackTrace;

    final Context StackTraceContext = new Context();

    final StringValue StackTraceValue;

    private DSeparator MessageSeparator;

    private DBeforeFirst MessageBeforeFirst;

    private DAfterLast MessageAfterLast;

    private DNone MessageNone;

    final List<String> list_Message;

    final Context MessageContext = new Context();

    final StringValue MessageValue;

    MInternalError(
            Macros macros) {

        setMacros(macros);
        this.list_StackTrace = new LinkedList<>();
        this.list_Message = new LinkedList<>();

        this.StackTraceValue
                = new StringValue(this.list_StackTrace, this.StackTraceContext);
        this.MessageValue
                = new StringValue(this.list_Message, this.MessageContext);
    }

    public void addAllStackTrace(
            List<String> strings) {

        if (this.macros == null) {
            throw ObjectMacroException.parameterNull("StackTrace");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }
        for (String string : strings) {
            if (string == null) {
                throw ObjectMacroException.parameterNull("StackTrace");
            }

            this.list_StackTrace.add(string);
        }
    }

    public void addStackTrace(
            String string) {

        if (string == null) {
            throw ObjectMacroException.parameterNull("StackTrace");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }

        this.list_StackTrace.add(string);
    }

    public void addAllMessage(
            List<String> strings) {

        if (this.macros == null) {
            throw ObjectMacroException.parameterNull("Message");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }
        for (String string : strings) {
            if (string == null) {
                throw ObjectMacroException.parameterNull("Message");
            }

            this.list_Message.add(string);
        }
    }

    public void addMessage(
            String string) {

        if (string == null) {
            throw ObjectMacroException.parameterNull("Message");
        }
        if (this.cacheBuilder != null) {
            throw ObjectMacroException
                    .cannotModify(this.getClass().getSimpleName());
        }

        this.list_Message.add(string);
    }

    private String buildStackTrace() {

        StringBuilder sb = new StringBuilder();
        List<String> strings = this.list_StackTrace;

        int i = 0;
        int nb_strings = strings.size();

        if (this.StackTraceNone != null) {
            sb.append(this.StackTraceNone.apply(i, "", nb_strings));
        }

        for (String string : strings) {

            if (this.StackTraceBeforeFirst != null) {
                string = this.StackTraceBeforeFirst.apply(i, string,
                        nb_strings);
            }

            if (this.StackTraceAfterLast != null) {
                string = this.StackTraceAfterLast.apply(i, string, nb_strings);
            }

            if (this.StackTraceSeparator != null) {
                string = this.StackTraceSeparator.apply(i, string, nb_strings);
            }

            sb.append(string);
            i++;
        }

        return sb.toString();
    }

    private String buildMessage() {

        StringBuilder sb = new StringBuilder();
        List<String> strings = this.list_Message;

        int i = 0;
        int nb_strings = strings.size();

        if (this.MessageNone != null) {
            sb.append(this.MessageNone.apply(i, "", nb_strings));
        }

        for (String string : strings) {

            if (this.MessageBeforeFirst != null) {
                string = this.MessageBeforeFirst.apply(i, string, nb_strings);
            }

            if (this.MessageAfterLast != null) {
                string = this.MessageAfterLast.apply(i, string, nb_strings);
            }

            if (this.MessageSeparator != null) {
                string = this.MessageSeparator.apply(i, string, nb_strings);
            }

            sb.append(string);
            i++;
        }

        return sb.toString();
    }

    StringValue getStackTrace() {

        return this.StackTraceValue;
    }

    StringValue getMessage() {

        return this.MessageValue;
    }

    private void initStackTraceDirectives() {

    }

    private void initMessageDirectives() {

    }

    @Override
    void apply(
            InternalsInitializer internalsInitializer) {

        internalsInitializer.setInternalError(this);
    }

    public String build() {

        CacheBuilder cache_builder = this.cacheBuilder;

        if (cache_builder == null) {
            cache_builder = new CacheBuilder();
        }
        else if (cache_builder.getExpansion() == null) {
            throw new InternalException("Cycle detection detected lately");
        }
        else {
            return cache_builder.getExpansion();
        }
        this.cacheBuilder = cache_builder;
        List<String> indentations = new LinkedList<>();

        initStackTraceDirectives();
        initMessageDirectives();

        StringBuilder sb0 = new StringBuilder();

        sb0.append("*** INTERNAL ERROR ***");
        sb0.append(LINE_SEPARATOR);
        sb0.append(LINE_SEPARATOR);
        sb0.append(buildStackTrace());
        sb0.append(LINE_SEPARATOR);
        sb0.append("An internal error was raised with the following message:");
        sb0.append(LINE_SEPARATOR);
        sb0.append(" ");
        sb0.append(buildMessage());
        sb0.append(".");
        sb0.append(LINE_SEPARATOR);
        sb0.append(LINE_SEPARATOR);
        sb0.append(
                "Please submit a defect ticket with the full error trace above on:");
        sb0.append(LINE_SEPARATOR);
        sb0.append(" http://sablecc.org/");

        cache_builder.setExpansion(sb0.toString());
        return sb0.toString();
    }

    @Override
    String build(
            Context context) {

        return build();
    }

    private void setMacros(
            Macros macros) {

        if (macros == null) {
            throw new InternalException("macros cannot be null");
        }

        this.macros = macros;
    }
}
