/*
 * Copyright © 2023 by Data Virtuality GmbH
 */
package org.teiid.dqp.internal.process;

import java.util.ListIterator;
import java.util.Stack;
import java.util.WeakHashMap;

/**
 * @author Roman Pedchenko
 * @date 2022.04.12
 */
public interface DVProcedureContext {
    String getSchema();

    String getProcName();

    String getName();

    class Store {
        private static final WeakHashMap<DQPWorkContext, Stack<DVProcedureContext>> procContext = new WeakHashMap<>();

        public static void push(DVProcedureContext ctx) {
            get().push(ctx);
        }

        public static DVProcedureContext peek() {
            final Stack<DVProcedureContext> ctxs = procContext.get(DQPWorkContext.getWorkContext());
            if (ctxs == null || ctxs.empty())
                return null;
            return ctxs.peek();
        }

        public static void pop() {
            final Stack<DVProcedureContext> ctxs = procContext.get(DQPWorkContext.getWorkContext());
            if (ctxs == null || ctxs.empty())
                return;
            ctxs.pop();
        }

        public static synchronized Stack<DVProcedureContext> get() {
            final DQPWorkContext key = DQPWorkContext.getWorkContext();
            final Stack<DVProcedureContext> got = procContext.getOrDefault(key, new Stack<>());
            procContext.putIfAbsent(key, got);
            return got;
        }

        public static String getTrace() {
            StringBuilder sb = new StringBuilder("Call trace:");
            Stack<DVProcedureContext> ctxStack = procContext.get(DQPWorkContext.getWorkContext());
            if (ctxStack != null) {
                final ListIterator<DVProcedureContext> ctxs = ctxStack.listIterator(ctxStack.size());
                while (ctxs.hasPrevious()) {
                    DVProcedureContext ctx = ctxs.previous();
                    sb.append("\n- ").append(ctx.getName());
                }
            } else
                sb.append(" <empty>");
            return sb.toString();
        }
    }
}
