package com.ttstd.adbloopback.adb;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

/**
 * ADB 流（对应 ADB 协议里的 OPEN/WRTE/OKAY/CLSE 多路复用）。
 * 本 demo 仅在单流场景下使用，内部通过 connection 的同步读写防止消息交错。
 */
public class AdbStream {
    private final AdbConnection connection;
    private final int localId;
    private final String destination;
    private int remoteId = -1;
    private boolean closed = false;
    private final Queue<byte[]> incoming = new LinkedList<>();
    private final Object lock = new Object();

    AdbStream(AdbConnection connection, int localId, String destination) {
        this.connection = connection;
        this.localId = localId;
        this.destination = destination;
    }

    void setRemoteId(int remoteId) {
        this.remoteId = remoteId;
    }

    public int write(byte[] data) throws IOException {
        synchronized (lock) {
            connection.sendInternal(AdbConstants.WRTE, localId, remoteId, data);
            // 等待对端 OKAY，其间若收到 WRTE 数据则先缓存起来
            while (true) {
                AdbMessage msg = connection.readMessage();
                if (msg.command == AdbConstants.OKAY) {
                    break;
                } else if (msg.command == AdbConstants.WRTE) {
                    incoming.add(msg.data);
                } else if (msg.command == AdbConstants.CLSE) {
                    closed = true;
                    break;
                } else {
                    break;
                }
            }
        }
        return data.length;
    }

    /** 读取对端发来的数据；无数据且对端未关闭时按 socket 超时返回 null。 */
    public byte[] read() throws IOException {
        synchronized (lock) {
            if (!incoming.isEmpty()) {
                return incoming.poll();
            }
            while (!closed) {
                try {
                    AdbMessage msg = connection.readMessage();
                    if (msg.command == AdbConstants.WRTE) {
                        incoming.add(msg.data);
                        return incoming.poll();
                    } else if (msg.command == AdbConstants.OKAY) {
                        // 暂无数据，继续等待
                    } else if (msg.command == AdbConstants.CLSE) {
                        closed = true;
                        break;
                    }
                } catch (IOException e) {
                    // 多为 socket 读超时，返回当前缓存（可能为 null）
                    break;
                }
            }
            return incoming.poll();
        }
    }

    public void close() throws IOException {
        synchronized (lock) {
            if (closed) return;
            try {
                connection.sendInternal(AdbConstants.CLSE, localId, remoteId, new byte[0]);
            } catch (IOException ignored) {
            }
            closed = true;
        }
    }

    public boolean isClosed() {
        return closed;
    }

    public String getDestination() {
        return destination;
    }
}
