package com.huangzj.server.demo;

import com.huangzj.cmd.gen.CmdEchoCts;
import com.huangzj.cmd.gen.CmdEchoStc;
import com.huangzj.cmd.gen.CmdRpcEnvelope;
import com.huangzj.cmd.gen.CrossForwardCts;
import com.huangzj.cmd.gen.CrossForwardStc;
import com.huangzj.cmd.gen.CrossProxyCts;
import com.huangzj.cmd.gen.CrossProxyStc;
import com.huangzj.cmd.gen.PbService;
import com.huangzj.cmd.gen.Service1_Method;
import com.huangzj.cmd.gen.Service2_Method;
import com.huangzj.cmd.gen.Service3_Method;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;

/**
 * 命令行压测三条客户端 TCP 路径：帧格式与区服 {@link com.huangzj.base.net.CmdRpcTcpFrameHandler} 一致。
 *
 * <p>运行：{@code java -cp ... com.huangzj.server.demo.TcpPathsDemo [host] [port]}
 */
public final class TcpPathsDemo {

    private TcpPathsDemo() {}

    public static void main(String[] args) throws Exception {
        String host = args.length > 0 ? args[0] : "127.0.0.1";
        int port = args.length > 1 ? Integer.parseInt(args[1]) : 9091;
        try (Socket socket = new Socket(host, port)) {
            socket.setSoTimeout(60_000);
            System.out.println("connected " + host + ":" + port);

            path1(socket);
            path2(socket);
            path3(socket);
        }
    }

    private static void path1(Socket socket) throws Exception {
        CmdRpcEnvelope req = CmdRpcEnvelope.newBuilder()
                .setServiceId(PbService.Service_1_VALUE)
                .setMethodId(Service1_Method.Method1_VALUE)
                .setPayload(CmdEchoCts.newBuilder()
                        .setText("path1-echo")
                        .build()
                        .toByteString())
                .build();
        CmdRpcEnvelope resp = sendRecv(socket, req);
        CmdEchoStc stc = CmdEchoStc.parseFrom(resp.getPayload());
        System.out.println("[path1] echo=" + stc.getText() + " serverTime=" + stc.getServerTimeMs());
    }

    private static void path2(Socket socket) throws Exception {
        CmdRpcEnvelope req = CmdRpcEnvelope.newBuilder()
                .setServiceId(PbService.Service_2_VALUE)
                .setMethodId(Service2_Method.Method2_VALUE)
                .setPayload(CrossProxyCts.newBuilder()
                        .setTrace("path2-trace")
                        .build()
                        .toByteString())
                .build();
        CmdRpcEnvelope resp = sendRecv(socket, req);
        CrossProxyStc stc = CrossProxyStc.parseFrom(resp.getPayload());
        System.out.println("[path2] trace=" + stc.getTrace()
                + " crossTime=" + stc.getCrossTimeMs()
                + " note=" + stc.getServerNote());
    }

    private static void path3(Socket socket) throws Exception {
        CmdRpcEnvelope req = CmdRpcEnvelope.newBuilder()
                .setServiceId(PbService.Service_3_VALUE)
                .setMethodId(Service3_Method.Method3_VALUE)
                .setPayload(CrossForwardCts.newBuilder()
                        .setTrace("path3-trace")
                        .build()
                        .toByteString())
                .build();
        CmdRpcEnvelope resp = sendRecv(socket, req);
        CrossForwardStc stc = CrossForwardStc.parseFrom(resp.getPayload());
        System.out.println("[path3] trace=" + stc.getTrace() + " crossTime=" + stc.getCrossTimeMs());
    }

    private static CmdRpcEnvelope sendRecv(Socket socket, CmdRpcEnvelope env) throws Exception {
        byte[] body = env.toByteArray();
        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
        out.writeInt(body.length);
        out.write(body);
        out.flush();
        DataInputStream in = new DataInputStream(socket.getInputStream());
        int len = in.readInt();
        byte[] resp = new byte[len];
        in.readFully(resp);
        return CmdRpcEnvelope.parseFrom(resp);
    }
}
