package com.pig4cloud.pig.statistics.socket;

import java.io.*;
import java.net.*;
import java.nio.file.*;

/**
 * TCP客户端测试类，用于测试服务器功能
 * 支持发送文本消息和图片文件
 */
public class TcpClient {
    // 协议定义，与服务器保持一致
    private static final byte PACKET_HEADER = 0x2;
    private static final byte PACKET_TAIL = 0x3;
    private static final byte TYPE_TEXT = 0x01;
    private static final byte TYPE_IMAGE = 0x02;
    
    private String serverHost;
    private int serverPort;
    private Socket socket;
    private InputStream in;
    private OutputStream out;
    
    public TcpClient(String serverHost, int serverPort) {
        this.serverHost = serverHost;
        this.serverPort = serverPort;
    }
    
    /**
     * 连接到服务器
     */
    public void connect() throws IOException {
        socket = new Socket(serverHost, serverPort);
        in = socket.getInputStream();
        out = socket.getOutputStream();
        System.out.println("已连接到服务器: " + serverHost + ":" + serverPort);
    }
    
    /**
     * 发送文本消息到服务器
     */
    public String sendText(String text) throws IOException {
        if (socket == null || socket.isClosed()) {
            throw new IOException("未连接到服务器，请先调用connect()方法");
        }
        
        byte[] data = text.getBytes("UTF-8");
        sendPacket(TYPE_TEXT, data);
        return receiveResponse();
    }
    
    /**
     * 发送图片文件到服务器
     */
    public String sendImage(String imageFilePath) throws IOException {
        if (socket == null || socket.isClosed()) {
            throw new IOException("未连接到服务器，请先调用connect()方法");
        }
        
        // 读取图片文件
        byte[] imageData = Files.readAllBytes(Paths.get(imageFilePath));
        sendPacket(TYPE_IMAGE, imageData);
        return receiveResponse();
    }
    
    /**
     * 按照协议格式发送数据包
     */
    private void sendPacket(int type, byte[] data) throws IOException {
        ByteArrayOutputStream packetBuffer = new ByteArrayOutputStream();
        
        // 写入包头
        packetBuffer.write(PACKET_HEADER);
        
        // 写入数据类型
        packetBuffer.write(type);
        
        // 写入数据长度（4字节，大端模式）
        packetBuffer.write((data.length >> 24) & 0xFF);
        packetBuffer.write((data.length >> 16) & 0xFF);
        packetBuffer.write((data.length >> 8) & 0xFF);
        packetBuffer.write(data.length & 0xFF);
        
        // 写入数据内容
        packetBuffer.write(data);
        
        // 写入包尾
        packetBuffer.write(PACKET_TAIL);
        
        // 发送数据包
        out.write(packetBuffer.toByteArray());
        out.flush();
    }
    
    /**
     * 接收服务器响应
     */
    private String receiveResponse() throws IOException {
        // 解析服务器响应的数据包
        ByteArrayOutputStream packetBuffer = new ByteArrayOutputStream();
        boolean inPacket = false;
        int dataType = -1;
        byte[] lengthBytes = new byte[4];
        int lengthIndex = 0;
        int contentLength = -1;
        ByteArrayOutputStream contentBuffer = new ByteArrayOutputStream();
        
        int b;
        while ((b = in.read()) != -1) {
            byte currentByte = (byte) b;
            
            // 处理包头
            if (!inPacket && currentByte == PACKET_HEADER) {
                inPacket = true;
                packetBuffer.reset();
                packetBuffer.write(currentByte);
                lengthIndex = 0;
                contentLength = -1;
                contentBuffer.reset();
                continue;
            }
            
            // 处理包内数据
            if (inPacket) {
                packetBuffer.write(currentByte);
                
                // 读取数据类型
                if (dataType == -1) {
                    dataType = currentByte & 0xFF;
                    continue;
                }
                
                // 读取数据长度（4字节）
                if (contentLength == -1) {
                    lengthBytes[lengthIndex++] = currentByte;
                    if (lengthIndex == 4) {
                        // 转换4字节为整数（大端模式）
                        contentLength = ((lengthBytes[0] & 0xFF) << 24) |
                                       ((lengthBytes[1] & 0xFF) << 16) |
                                       ((lengthBytes[2] & 0xFF) << 8) |
                                       (lengthBytes[3] & 0xFF);
                    }
                    continue;
                }
                
                // 读取数据内容
                if (contentBuffer.size() < contentLength) {
                    contentBuffer.write(currentByte);
                    
                    // 检查是否已读取所有内容
                    if (contentBuffer.size() == contentLength) {
                        // 接下来应该是包尾
                        continue;
                    }
                } else {
                    // 检查包尾
                    if (currentByte == PACKET_TAIL) {
                        // 完整包接收完成，返回内容
                        return new String(contentBuffer.toByteArray(), "UTF-8");
                    } else {
                        // 包尾不正确，视为无效包
                        throw new IOException("收到无效的数据包，包尾不正确");
                    }
                }
            }
        }
        
        throw new IOException("与服务器的连接已关闭");
    }
    
    /**
     * 关闭与服务器的连接
     */
    public void disconnect() {
        try {
            if (in != null) in.close();
            if (out != null) out.close();
            if (socket != null && !socket.isClosed()) {
                socket.close();
                System.out.println("已断开与服务器的连接");
            }
        } catch (IOException e) {
            System.err.println("关闭连接时发生错误: " + e.getMessage());
        }
    }
    
    /**
     * 测试方法
     */
    public static void main(String[] args) {
        // 服务器地址和端口
        String host = "localhost";
        int port = 8888;
        
        TcpClient client = new TcpClient(host, port);
        
        try {
            // 连接服务器
            client.connect();
            
            // 测试发送文本
            String text = "Hello, TCP Server!";
            System.out.println("发送文本: " + text);
            String textResponse = client.sendText(text);
            System.out.println("服务器响应: " + textResponse);
            
            // 测试发送图片（请替换为实际的图片路径）
            String imagePath = "C:\\Users\\L\\Desktop\\素材\\image16.png"; // 测试图片路径
            System.out.println("发送图片: " + imagePath);
            String imageResponse = client.sendImage(imagePath);
            System.out.println("服务器响应: " + imageResponse);
            
        } catch (IOException e) {
            System.err.println("客户端错误: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 断开连接
            client.disconnect();
        }
    }
}
