package tracker;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URL;

import org.simpleframework.http.Request;
import org.simpleframework.http.Response;
import org.simpleframework.http.core.Container;

/**
 * 拦截 announce 请求，打印参数后转发给真实 Tracker。
 */
public class DataCaptureProxy implements Container {

    private final String trackerHost;
    private final int    trackerPort;
    private final Tracker tracker;

    public DataCaptureProxy(String trackerHost, int trackerPort) {
        this.trackerHost = trackerHost;
        this.trackerPort = trackerPort;
        this.tracker = new Tracker(); // 初始化 Tracker 实例
    }

    @Override
    public void handle(Request req, Response resp) {
        try {
            // 提取并打印关键参数
            String infoHash   = req.getParameter("info_hash");
            String uploaded   = req.getParameter("uploaded");
            String downloaded = req.getParameter("downloaded");
            String passkey    = req.getParameter("passkey");

            // 获取客户端IP地址
            String clientIp;
            // 直接从 TCP 连接（socket 源地址）中读取
            SocketAddress socketAddress = req.getClientAddress();
            if (socketAddress instanceof InetSocketAddress) {
                clientIp = ((InetSocketAddress) socketAddress)
                               .getAddress()
                               .getHostAddress();
            } else {
                // 兜底写法，将整个 SocketAddress 转为字符串
                clientIp = socketAddress.toString();
            }

            System.out.println(
                "Captured announce → info_hash=" + infoHash +
                ", uploaded=" + uploaded +
                ", downloaded=" + downloaded +
                ", passkey=" + passkey +
                ", client_ip=" + clientIp
            );

            // 调用 Tracker 方法更新上传和下载数据
            if (passkey != null && !passkey.isEmpty()) {
                try {
                    if (uploaded != null && !uploaded.isEmpty()) {
                        int uploadValue = Integer.parseInt(uploaded);
                        if (uploadValue > 0) {
                            tracker.AddUpLoad(passkey, uploadValue);
                        }
                    }
                    
                    if (downloaded != null && !downloaded.isEmpty()) {
                        int downloadValue = Integer.parseInt(downloaded);
                        if (downloadValue > 0) {
                            tracker.AddDownload(passkey, downloadValue);
                        }
                    }
                } catch (NumberFormatException e) {
                    System.err.println("Error parsing upload/download values: " + e.getMessage());
                }
            }

            // 构造转发 URL
            String path = req.getPath().getPath();
            String query = req.getQuery().toString();
            String targetUrl = "http://" + trackerHost + ":" + trackerPort
                             + path + "?" + query;

            HttpURLConnection connection =
                (HttpURLConnection) new URL(targetUrl).openConnection();
            connection.setRequestMethod("GET");

            // 转发响应码和类型
            resp.setCode(connection.getResponseCode());
            String ct = connection.getContentType();
            if (ct != null) resp.setValue("Content-Type", ct);

            // 转发响应体
            try (InputStream in = connection.getInputStream();
                 OutputStream out = resp.getOutputStream()) {
                byte[] buf = new byte[8192];
                int  len;
                while ((len = in.read(buf)) != -1) {
                    out.write(buf, 0, len);
                }
            }

        } catch (Exception e) {
            try {
                resp.setCode(500);
                resp.close();
            } catch (Exception ignore) {}
            e.printStackTrace();
        }
    }
}
