// Copyright (c) 2018 Peter Ohler. All rights reserved.
// Licensed under the MIT License. See LICENSE file in the project root for license details.

#include "trace.h"

#include "parse.h"

#define MAX_INDENT 256

static void fill_indent(char *indent, int depth) {
    if (MAX_INDENT <= depth) {
        depth = MAX_INDENT - 1;
    } else if (depth < 0) {
        depth = 0;
    }
    if (0 < depth) {
        memset(indent, ' ', depth);
    }
    indent[depth] = '\0';
}

void oj_trace(const char *func, VALUE obj, const char *file, int line, int depth, TraceWhere where) {
    char fmt[64];
    char indent[MAX_INDENT];

    depth *= 2;
    fill_indent(indent, depth);
    sprintf(fmt, "#0:%%13s:%%3d:Oj:%c:%%%ds %%s %%s\n", where, depth);
    printf(fmt, file, line, indent, func, rb_obj_classname(obj));
}

void oj_trace_parse_call(const char *func, ParseInfo pi, const char *file, int line, VALUE obj) {
    char fmt[64];
    char indent[MAX_INDENT];
    int  depth = (int)(stack_size(&pi->stack) * 2);

    fill_indent(indent, depth);
    sprintf(fmt, "#0:%%13s:%%3d:Oj:-:%%%ds %%s %%s\n", depth);
    printf(fmt, file, line, indent, func, rb_obj_classname(obj));
}

void oj_trace_parse_in(const char *func, ParseInfo pi, const char *file, int line) {
    char fmt[64];
    char indent[MAX_INDENT];
    int  depth = (int)(stack_size(&pi->stack) * 2);

    fill_indent(indent, depth);
    sprintf(fmt, "#0:%%13s:%%3d:Oj:}:%%%ds %%s\n", depth);
    printf(fmt, file, line, indent, func);
}

void oj_trace_parse_hash_end(ParseInfo pi, const char *file, int line) {
    char  fmt[64];
    char  indent[MAX_INDENT];
    int   depth = (int)(stack_size(&pi->stack) * 2 - 2);
    Val   v     = stack_peek(&pi->stack);
    VALUE obj   = v->val;

    fill_indent(indent, depth);
    sprintf(fmt, "#0:%%13s:%%3d:Oj:{:%%%ds hash_end %%s\n", depth);
    printf(fmt, file, line, indent, rb_obj_classname(obj));
}

void oj_trace_parse_array_end(ParseInfo pi, const char *file, int line) {
    char fmt[64];
    char indent[MAX_INDENT];
    int  depth = (int)(stack_size(&pi->stack) * 2);

    fill_indent(indent, depth);
    sprintf(fmt, "#0:%%13s:%%3d:Oj:{:%%%ds array_ned\n", depth);
    printf(fmt, file, line, indent);
}
