#include <stdio.h>
#include <stdlib.h>
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "image_from_sftp.h"



void print_error(const char *message) {
    fprintf(stderr, "%s: %d\n", message, libssh2_session_last_error(NULL, NULL, NULL, 0));
}

int create_socket(const char *hostname, int port) {
    int sock;
    struct sockaddr_in sin;
    
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        print_error("Failed to create socket");
        return -1;
    }

    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    inet_pton(AF_INET, hostname, &sin.sin_addr);

    if (connect(sock, (struct sockaddr *)(&sin), sizeof(struct sockaddr_in)) != 0) {
        close(sock);
        print_error("Failed to connect to server");
        return -1;
    }

    return sock;
}

char *filepathname (char*filepath,char*filename){
    size_t fullPathLength = strlen(filepath) + strlen(filename) + 1;
    // 动态分配内存
    char *fullPath = (char *)malloc(fullPathLength);
    if (fullPath == NULL) {
        perror("Failed to allocate memory");
        return NULL;
    }
    strcpy(fullPath, filepath);
    strcat(fullPath, filename);
    return fullPath;
}

int upload_file(char *localfilename,char *remotefilename) {
    int rc;
    LIBSSH2_SESSION *session;
    LIBSSH2_SFTP *sftp;
    LIBSSH2_SFTP_HANDLE *sftp_handle;
    char *mem;
    size_t nread;
    size_t total = 0;
    struct stat fileinfo;
    FILE *local;
    const char *hostname = Hostname;
    const int port= Port;
    const char *username = Username;
    const char *password = Password;
    const char *localfile = NULL;
    const char *remotefile = NULL;
    char *localfilePath = LocalfilePath;
    char *remotefilePath = RemotefilePath;
    localfile = filepathname (localfilePath , localfilename);
    remotefile = filepathname (remotefilePath , remotefilename);
    // Initialize libssh2
    if (libssh2_init(0) != 0) {
        print_error("Failed to initialize libssh2");
        return -1;
    }

    // Create a session instance
    session = libssh2_session_init();
    if (session == NULL) {
        print_error("Failed to create SSH session");
        return -1;
    }

   
    // Start the session
    int sock = create_socket(hostname,port);
    if (libssh2_session_handshake(session, sock) != 0) {
        print_error("Failed to establish SSH session");
        libssh2_session_free(session);
        return -1;
    }

    // Authenticate
    if (libssh2_userauth_password(session, username, password) != 0) {
        print_error("Failed to authenticate");
        libssh2_session_free(session);
        return -1;
    }

    // Initialize SFTP session
    sftp = libssh2_sftp_init(session);
    if (!sftp) {
        print_error("Failed to initialize SFTP session");
        libssh2_session_free(session);
        return -1;
    }

    // Open the remote file for writing
    sftp_handle = libssh2_sftp_open(sftp, remotefile, LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC, 0644);
    if (!sftp_handle) {
        print_error("Failed to open remote file");
        libssh2_sftp_shutdown(sftp);
        libssh2_session_free(session);
        return -1;
    }

    // Open the local file for reading
    local = fopen(localfile, "rb");
    if (!local) {
        print_error("Failed to open local file");
        libssh2_sftp_close(sftp_handle);
        libssh2_sftp_shutdown(sftp);
        libssh2_session_free(session);
        return -1;
    }

    // Get the file size
    if (fstat(fileno(local), &fileinfo) != 0) {
        print_error("Failed to get file size");
        fclose(local);
        libssh2_sftp_close(sftp_handle);
        libssh2_sftp_shutdown(sftp);
        libssh2_session_free(session);
        return -1;
    }
    size_t filesize = fileinfo.st_size;

    // Read from local and write to remote
    while (total < filesize) {
        char buffer[1024];
        nread = fread(buffer, 1, sizeof(buffer), local);
        if (nread < 0) {
            print_error("Error reading from local file");
            break;
        }
        if (nread > 0) {
            libssh2_sftp_write(sftp_handle, buffer, nread);
            total += nread;
        }
    }

    // Cleanup
    fclose(local);
    libssh2_sftp_close(sftp_handle);
    libssh2_sftp_shutdown(sftp);
    libssh2_session_disconnect(session, "Normal Shutdown");
    libssh2_session_free(session);
    libssh2_exit();

    return 0;
}

int download_file(char *argv , char *file_format) {
    char *str = argv;
    char *value = NULL ;
    char *key = "\"action_name\": \"/guest/";
    char *perior_action[Perior_action_count];
    int perior_action_count=0;
    char *start = strstr(str, key);
    int length_file_format = strlen (file_format);
    while (start)
    {
        start =start+ strlen(key) /*+ 4*/;  // 跳过键部分，指向值的开始
        char *end = strstr(start, "\"");
        //end +=2 ;  // 查找值的结束引号
        int length = end - start ;
        value = (char *)malloc(length + 1 + length_file_format); // +1 用于存储字符串结束符
        if (value == NULL) printf("Memory allocation failed\n");
        if (end) {
            // 复制值到 value 中
            strncpy(value, start, length);
            value[length] = '\0';  // 添加字符串结束符
            strcat(value , file_format);
        }
        perior_action[perior_action_count]=value;
        perior_action_count++;
        start = strstr(end, key);

    }   
    //printf ("argv1:%s\n",argv[1]);
    char *localfilepath[perior_action_count];
    if (perior_action_count != 0){
    for (int i = 0; i < perior_action_count; i++){
        printf("perior action:%s\n",perior_action[i]);
        localfilepath[i] = filepathname(LocalfilePath,perior_action[i]);
        perior_action[i] = filepathname(RemotefilePath , perior_action[i]);
        }
    }    
    //const char *actvation_id = getenv("__OW_ACTIVATION_ID"); 
    //const char *action = getenv("__OW_ACTION_NAME");
    //printf("{\"action_name\" : \"%s\", \"activation_id\":\"%s\",\"message\":  \" hello world!\" }\n",action,actvation_id);    
    int sock;
    LIBSSH2_SESSION *session;
    LIBSSH2_SFTP *sftp;
    LIBSSH2_SFTP_HANDLE *sftp_handle;
    ssize_t nread;
    char *hostname = Hostname;
    int port= Port;
    char *username = Username;
    char *password = Password;
    char *localfilePath = LocalfilePath ; 
    char *localfile = NULL;
    char *remotefilePath = RemotefilePath ; 
    char *remotefile = NULL;
    //remotefile = filepathname(remotefilePath,filename);
    //localfile = filepathname (localfilePath,filename);

    // Initialize libssh2
    if (libssh2_init(0) != 0) {
        print_error("Failed to initialize libssh2");
        return -1;
    }

    // Create a socket and connect
    sock = create_socket(hostname, port);
    if (sock < 0) {
        return -1;
    }

    // Create a session instance
    session = libssh2_session_init();
    if (session == NULL) {
        close(sock);
        print_error("Failed to create SSH session");
        return -1;
    }

    // Start the session
    if (libssh2_session_handshake(session, sock) != 0) {
        print_error("Failed to establish SSH session");
        libssh2_session_free(session);
        close(sock);
        return -1;
    }

    // Authenticate
    if (libssh2_userauth_password(session, username, password) != 0) {
        print_error("Failed to authenticate");
        libssh2_session_free(session);
        close(sock);
        return -1;
    }

    // Initialize SFTP session
    sftp = libssh2_sftp_init(session);
    if (!sftp) {
        print_error("Failed to initialize SFTP session");
        libssh2_session_free(session);
        close(sock);
        return -1;
    }

    for (int i = 0; i < perior_action_count; i++) {
    // Open the remote file for reading
    char buffer[1024];
    sftp_handle = libssh2_sftp_open(sftp, perior_action[i], LIBSSH2_FXF_READ, 0);
    if (!sftp_handle) {
        print_error("Failed to open remote file");
        libssh2_sftp_shutdown(sftp);
        libssh2_session_free(session);
        close(sock);
        return -1;
    }

    // Open the local file for writing
    FILE *local = fopen(localfilepath[i], "wb");
    if (!local) {
        print_error("Failed to open local file");
        libssh2_sftp_close(sftp_handle);
        libssh2_sftp_shutdown(sftp);
        libssh2_session_free(session);
        close(sock);
        return -1;
    }

    // Read from remote and write to local
    while ((nread = libssh2_sftp_read(sftp_handle, buffer, sizeof(buffer))) > 0) {
        fwrite(buffer, 1, nread, local);
    }

    if (nread < 0) {
        print_error("Error reading from remote file");
    }
    fclose(local);
    libssh2_sftp_close(sftp_handle);
    }    

    // Cleanup
    libssh2_sftp_shutdown(sftp);
    libssh2_session_disconnect(session, "Normal Shutdown");
    libssh2_session_free(session);
    close(sock);
    libssh2_exit();

    return 0;
}

int main (){
    upload_file("test.jpg","noop2.jpg");
    upload_file("test.jpg","noop3.jpg");
    download_file(" {\"__ow_body\": [{\"action_name\": \"/guest/noop2\", \"activation_id\": \"05a456e67d1247d7a456e67d12e7d7e4\", \"message\": \" hello world!\"}, {\"action_name\": \"/guest/noop3\", \"activation_id\": \"760ab5cf657d4a078ab5cf657d6a0798\", \"message\": \" hello world!\"}], \"__ow_headers\": {\"accept\": \"*/*\", \"accept-encoding\": \"gzip, deflate\", \"content-type\": \"application/json\", \"host\": \"controllers\", \"user-agent\": \"python-requests/2.18.4\", \"x-forwarded-for\": \"172.17.0.1\", \"x-forwarded-host\": \"172.17.0.1\", \"x-forwarded-port\": \"8080\", \"x-forwarded-proto\": \"http\", \"x-forwarded-url\": \"http://172.17.0.1/api/23bc46b1-71f6-4ed5-8c54-816aa4f8c502/noop4-api/noop4-path\", \"x-real-ip\": \"172.17.0.1\", \"x-request-id\": \"7b11d572a3f0ed4ff57394717b3ac473\"}, \"__ow_method\": \"post\", \"__ow_path\": \"\"} ",".jpg");
    return 0;
}

