#include <winsock2.h>
#include <ws2tcpip.h>

#include <chrono>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <thread>

constexpr int BUFFER_SIZE = 4096;

int main(int argc, char** argv)
{
    if (argc == 1) {
        std::cout << "Need Param, Example: send 127.0.0.1 9696 E:\\2.bmp\n";
        return 0;
    }

    // 初始化Winsock
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "Failed to initialize Winsock." << std::endl;
        return 1;
    }

    // 创建套接字
    SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "Failed to create socket." << std::endl;
        WSACleanup();
        return 1;
    }

    // 设置服务器地址
    sockaddr_in serverAddress{};
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(std::stoi(std::string(argv[2])));
    if (inet_pton(AF_INET, argv[1], &(serverAddress.sin_addr)) <= 0) {
        std::cerr << "Invalid server address." << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }

    // 连接到服务器
    if (connect(clientSocket, reinterpret_cast<sockaddr*>(&serverAddress),
                sizeof(serverAddress)) == SOCKET_ERROR) {
        std::cerr << "Failed to connect to server." << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }

    // 打开要发送的文件
    FILE* file = std::fopen(argv[3], "rb");
    if (!file) {
        std::cerr << "Failed to open file : " << argv[3] << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }

    int Second = 3;
    std::cout << Second << " Second after to start send .....\n";
    std::this_thread::sleep_for(std::chrono::milliseconds(Second * 1000));
    // 读取文件内容并发送到服务器
    size_t allLen = 0;
    char   buffer[BUFFER_SIZE];
    while (!std::feof(file)) {
        int nSize = std::fread(buffer, sizeof(char), BUFFER_SIZE, file);
        if (nSize > 0) {
            allLen += nSize;

            if (send(clientSocket, buffer, nSize, 0) == SOCKET_ERROR) {
                std::cerr << "Failed to send data to server." << std::endl;
                break;
            }
            std::cout << "already send Size = " << allLen << "\n";
        }
    }

    // 关闭套接字和文件
    std::fclose(file);
    closesocket(clientSocket);
    WSACleanup();

    std::cout << "Send Done, Size = " << allLen << std::endl;
    return 0;
}