const fs = require('fs');
const path = require('path');
const axios = require('axios');
const FormData = require('form-data');
const {lockFile, unlockFile} = require("../helpers/lock_mechanism");
const {decryptFileInPlace, encryptFileInPlace} = require("../src/main/aes_encrypt");

async function decryptAndGetServerIP(filePath) {
    try {
        await lockFile(filePath);
        await decryptFileInPlace(filePath);

        const fileContent = await fs.promises.readFile(filePath, 'utf8');
        const jsonData = JSON.parse(fileContent);
        const serverIP = jsonData.ip;

        await encryptFileInPlace(filePath)
        await unlockFile(filePath);
        return serverIP;
    } catch (error) {
        console.error('An error occurred:', error);
        return null;
    }
}

async function extractId() {
    try {
        // Path to the JSON file
        const jsonFilePath = path.join(__dirname, '..', 'loginData.json');

        // Read and parse the JSON file
        const jsonData = await fs.promises.readFile(jsonFilePath, 'utf-8');
        const { id } = JSON.parse(jsonData);

        return id;
    } catch (error) {
        console.error('Failed to read file or parse data:', error);
        throw error;
    }
}

async function uploadFile(filePath, serverIp) {
    try {
        const idUser = await extractId();  // Fetch ID from JSON
        const nameOfFile = path.basename(filePath);  // Extract the file name from the path

        // Ensure the file exists and get its size
        if (!fs.existsSync(filePath)) {
            console.error("File does not exist: " + filePath);
            process.exit(1);
        }
        const fileSizeInBytes = fs.statSync(filePath).size;

        const form = new FormData();
        form.append('idUser', idUser);
        form.append('nameOfFile', nameOfFile);
        form.append('sizeOfFile', fileSizeInBytes);
        form.append('file', fs.createReadStream(filePath));

        const response = await axios.post(`http://${serverIp}/upload`, form, {
            headers: {
                ...form.getHeaders(),
            },
        });

        console.log('File uploaded successfully:', response.data);
        process.exit(0); // Exit with status 0 (success)
    } catch (error) {
        console.error('Error uploading file:', error.message);
        process.exit(1); // Exit with status 1 (error)
    }
}

// Command-line argument for file path
if (process.argv.length < 3) {
    console.log('Usage: node <script> <filePath>');
    process.exit(1);
}

const filePath = process.argv[2]; // The third command-line argument is the file path
let serverIp = null

decryptAndGetServerIP(path.join(__dirname, '..', 'ipConfig.json')).then(ip => {
    serverIp = ip;
});

uploadFile(filePath, serverIp).catch(err => {
    console.error(err);
    process.exit(1); // Ensure to exit with status 1 in case of promise rejection
});
