package org.zstack.testlib;

import com.sun.demo.jvmti.hprof.Tracker;
import org.apache.logging.log4j.ThreadContext;
import org.zstack.core.Platform;
import org.zstack.core.cloudbus.CloudBus;
import org.zstack.header.Constants;
import org.zstack.header.message.AbstractBeforeSendMessageInterceptor;
import org.zstack.header.message.CarrierMessage;
import org.zstack.header.message.Message;
import org.zstack.header.message.MessageReply;
import org.zstack.header.rest.BeforeAsyncJsonPostInterceptor;
import org.zstack.header.rest.RESTFacade;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * Created by xing5 on 2017/3/24.
 */
public class ApiPathTracker {
    private CloudBus bus;
    private RESTFacade restf;

    List<Path> paths = new ArrayList<>();

    private enum Type {
        Message,
        HttpRPC,
    }

    private static class Path {
        Type type;
        String path;
    }

    public List<String> getApiPath() {
        return paths.stream().map(p -> String.format("(%s) %s", p.type, p.path)).collect(Collectors.toList());
    }

    public ApiPathTracker(String apiId) {
        bus = Platform.getComponentLoader().getComponent(CloudBus.class);
        restf = Platform.getComponentLoader().getComponent(RESTFacade.class);

        bus.installBeforeSendMessageInterceptor(new AbstractBeforeSendMessageInterceptor() {
            @Override
            public void intercept(Message msg) {
                if (msg instanceof MessageReply || msg instanceof CarrierMessage) {
                    return;
                }

                String id = ThreadContext.get(Constants.THREAD_CONTEXT_API);

                if (id == null || !id.equals(apiId)) {
                    return;
                }

                Path p = new Path();
                p.type = Type.Message;
                p.path = msg.getClass().getName();
                paths.add(p);
            }
        });

        restf.installBeforeAsyncJsonPostInterceptor(new BeforeAsyncJsonPostInterceptor() {
            @Override
            public void beforeAsyncJsonPost(String url, Object body, TimeUnit unit, long timeout) {
                String id = ThreadContext.get(Constants.THREAD_CONTEXT_API);

                if (id == null || !id.equals(apiId)) {
                    return;
                }

                Path p = new Path();
                p.type = Type.HttpRPC;
                p.path = String.format("[url:%s, cmd: %s]", url, body.getClass().getName());
                paths.add(p);
            }

            @Override
            public void beforeAsyncJsonPost(String url, String body, TimeUnit unit, long timeout) {
            }
        });
    }
}

@@ -2709,32 +2709,395 @@
 long timeout) %7B%0A
+                String id = ThreadContext.get(Constants.THREAD_CONTEXT_API);%0A%0A                if (id == null %7C%7C !id.equals(apiId)) %7B%0A                    return;%0A                %7D%0A%0A                Path p = new Path();%0A                p.type = Type.HttpRPC;%0A                p.path = String.format(%22%5Burl:%25s, cmd body: %25s%5D%22, url, body);%0A                paths.add(p);%0A
             %7D%0A  

fix ApiPathTracker