#include "common.h"

typedef struct ftp_file
{
    char cmd[MAXLINE];  // FTP命令
    char filename[MAXLINE]; // 文件名参数
    char fileSize[MAXLINE]; // 文件大小参数
} ftp_file_t;

void toggle(int conn_sock,int hit)
{
    size_t n; int i,no=0;
    char buf[MAXBUF];
    ftp_file_t file;
    char filePath[MAXLINE] = "./"; // 假设当前目录下有文件

    printf("第%d个客户通信开始\n",hit);
    while((n =recv(conn_sock, &file, sizeof(ftp_file_t),0))> 0) {
        printf("toggle服务器收到第%d个客户第%d个消息,长度为%d字节\n", hit,++no,(int)n);
        if (strcmp(file.cmd,"put")==0)
        {
            int fileSize = atoi(file.fileSize);
            char *fileContent = malloc(fileSize);
            recv(conn_sock, fileContent, fileSize, 0); // 接收文件内容
            FILE *fp = fopen(file.filename, "w");
            if (fp == NULL) {
                perror("Error opening file for writing");
            } else {
                fwrite(fileContent, 1, fileSize, fp); // 将接收到的内容写入文件
                fclose(fp);
            }
            free(fileContent);
            strcpy(buf, "File received successfully\n");
            send (conn_sock, buf, strlen(buf), 0);
        }
        else if (strcmp(file.cmd,"get")==0)
        {
            strcat(filePath, file.filename); // 构建完整文件路径
            FILE *fp = fopen(filePath, "r");
            if (fp == NULL) {
                perror("Error opening file for reading");
                strcpy(file.fileSize, "0");
                send(conn_sock, &file, sizeof(ftp_file_t), 0); // 发送错误信息
            } else {
                fseek(fp, 0, SEEK_END);
                long fileSize = ftell(fp);
                fclose(fp);
                snprintf(file.fileSize, MAXLINE, "%ld", fileSize); // 将文件大小转换为字符串并存储
                send(conn_sock, &file, sizeof(ftp_file_t), 0); // 发送文件信息
                fp = fopen(filePath, "r");
                if (fp != NULL) {
                    char *fileContent = malloc(fileSize);
                    fread(fileContent, 1, fileSize, fp); // 从文件中读取内容到缓冲区
                    fclose(fp);
                    send(conn_sock, fileContent, fileSize, 0); // 发送文件内容
                    free(fileContent);
                    strcpy(buf, "File sent successfully\n");
                    send (conn_sock, buf, strlen(buf), 0);
                }
            }
        }

    }
    printf("第%d个客户通信结束\n",hit);
}

int main(int argc, char **argv) 
{
    int listen_sock, conn_sock, port, clientlen;
    struct sockaddr_in clientaddr;
    struct hostent *hp;
    char *haddrp;
    int hit;
	
    if (argc != 2) {
	    fprintf(stderr, "usage: %s <port>\n", argv[0]);
	    exit(1);
    }
    port = atoi(argv[1]);

    listen_sock = open_listen_sock(port);    
    if( listen_sock==-1) {
    	printf("端口号%d繁忙\n",port);
    	exit(1);
    }
    
    for (hit=1; ; hit++) {
	    clientlen = sizeof(clientaddr);
	    conn_sock = accept(listen_sock, (SA *)&clientaddr, &clientlen);

	    /* determine the domain name and IP address of the client */
	    hp = gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, 
			   sizeof(clientaddr.sin_addr.s_addr), AF_INET);
	    haddrp = inet_ntoa(clientaddr.sin_addr);
	    printf("server connected to %s (%s)\n", hp->h_name, haddrp);

	    toggle(conn_sock,hit);
	    close(conn_sock);
    }
    exit(0);
}
