from flask import Flask, render_template, jsonify, request
import requests
from bs4 import BeautifulSoup
from ftplib import FTP, all_errors as ftp_errors
from ftplib import FTP, error_perm
import socket
import logging
import time
# Set up logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
import os

app = Flask(__name__)

# FTP server details
FTP_SERVER = "195.35.29.48"
FTP_USER = "ftpuser"
FTP_PASS = "Abcd1234"  # Replace with your FTP password

# URL of the FTP directory
SOURCE_DIR = "NudgeDisplay/Input/EPD_4_2"  # FTP source directory
DEST_DIR = "Name_Board/EPD_4_2/"  # FTP destination directory
LOCAL_SAVE_DIR = "downloads/"  # Local directory to save downloaded files


@app.route('/')
def index():
    return render_template('index.html')

@app.route('/get-folder-contents')
def get_folder_contents():
    directory = request.args.get('dir')
    if not directory:
        return jsonify({"error": "No directory specified"}), 400
    try:
        # Use the full URL of the image server here
        response = requests.get(f"http://195.35.29.48:8080/ftpuser/{directory}")
        response.raise_for_status()
        soup = BeautifulSoup(response.text, 'html.parser')
        links = soup.find_all('a')
        files = [link.get('href') for link in links if link.get('href').lower().endswith(('.jpg', '.png'))]
        return jsonify(files)
    except requests.RequestException as e:
        return jsonify({"error": str(e)}), 500

def upload_files_to_ftp(ftp_server, ftp_user, ftp_pass, local_dir, upload_dir, files_to_upload):
    logger.debug(f"Starting upload_files_to_ftp for {len(files_to_upload)} files")
    try:
        with FTP(ftp_server, timeout=30) as ftp:
            ftp.set_debuglevel(2)  # Enable FTP debugging
            ftp.login(ftp_user, ftp_pass)
            ftp.set_pasv(True)  # Use passive mode
            logger.info(f"Logged in to FTP server for upload. Current directory: {ftp.pwd()}")

            logger.debug(f"Changing to directory: {upload_dir}")
            ftp.cwd(upload_dir)
            logger.info(f"Changed to directory: {ftp.pwd()}")

            for file_name in files_to_upload:
                local_file_path = os.path.join(local_dir, file_name)
                logger.debug(f"Uploading file: {file_name}")
                with open(local_file_path, 'rb') as local_file:
                    ftp.storbinary(f"STOR {file_name}", local_file)
                logger.info(f"Uploaded: {file_name}")
        
        logger.debug("upload_files_to_ftp completed successfully")
        return True
    except Exception as e:
        logger.exception(f"Error during upload: {e}")
        return False

def clear_ftp_directory(ftp, directory):
    logger.debug(f"Clearing FTP directory: {directory}")
    try:
        ftp.cwd(directory)
        files = ftp.nlst()
        logger.info(f"Files in directory before clearing: {files}")
        
        for file_name in files:
            try:
                ftp.delete(file_name)
                logger.info(f"Deleted {file_name} from {directory}")
            except Exception as e:
                logger.error(f"Error deleting {file_name} from {directory}: {str(e)}")
        
    except Exception as e:
        logger.exception(f"Error accessing directory {directory} for clearing: {str(e)}")
    logger.debug(f"Directory clearing completed. Current directory: {ftp.pwd()}")

@app.route('/process-selection', methods=['POST'])
def process_selection():
    logger.debug(f"Starting process_selection at {time.time()}")
    
    data = request.json
    directory = data.get('directory')
    selected_image = data.get('selectedImage')
    logger.info(f"Directory: {directory}, Selected image: {selected_image}")
    
    if not selected_image:
        logger.warning("No image selected")
        return 'No image selected', 400

    try:
        folder_name = os.path.splitext(selected_image)[0]
        folder_path = os.path.join(directory, folder_name)
        logger.info(f"Folder path: {folder_path}")

        if not os.path.exists(LOCAL_SAVE_DIR):
            os.makedirs(LOCAL_SAVE_DIR)
            logger.info(f"Created local save directory: {LOCAL_SAVE_DIR}")

        logger.debug("Connecting to FTP server...")
        with FTP(FTP_SERVER, timeout=30) as ftp:
            logger.debug("FTP connection established")
            ftp.set_debuglevel(2)  # Enable FTP debugging
            ftp.login(FTP_USER, FTP_PASS)
            logger.info(f"Logged in to FTP server {FTP_SERVER} as {FTP_USER}")
            ftp.set_pasv(True)  # Try passive mode

            try:
                logger.debug(f"Changing to directory: {folder_path}")
                ftp.cwd(folder_path)
                logger.info(f"Successfully changed to directory: {folder_path}")
            except error_perm as e:
                logger.error(f"Error accessing directory {folder_path}: {str(e)}")
                return f"Error accessing directory {folder_path}: {str(e)}", 400

            downloaded_files = []
            def download_file(name):
                if name.endswith('.h'):
                    local_file_path = os.path.join(LOCAL_SAVE_DIR, name)
                    logger.debug(f"Attempting to download: {name}")
                    try:
                        with open(local_file_path, 'wb') as local_file:
                            ftp.retrbinary(f"RETR {name}", local_file.write)
                        logger.info(f"Successfully downloaded: {name}")
                        downloaded_files.append(name)
                    except Exception as e:
                        logger.error(f"Error downloading {name}: {str(e)}")

            try:
                logger.debug("Listing directory contents...")
                files = []
                ftp.retrlines('NLST', files.append)
                logger.info(f"Files in directory: {files}")
                
                for file in files:
                    download_file(file)
                
                logger.info("Directory listing and download completed")
            except socket.timeout:
                logger.error("Timeout occurred while listing directory contents")
                return "Timeout occurred while listing directory contents", 504
            except Exception as e:
                logger.error(f"Error listing directory contents: {str(e)}")
                return f"Error listing directory contents: {str(e)}", 500

            if not downloaded_files:
                logger.warning("No .h files found in the directory")
                return "No .h files found in the directory.", 404

        DEST_DIR = directory.replace("Input", "Output")
        logger.info(f"Uploading files to the destination directory {DEST_DIR}...")
        upload_result = upload_files_to_ftp(FTP_SERVER, FTP_USER, FTP_PASS, LOCAL_SAVE_DIR, DEST_DIR, downloaded_files)
        if not upload_result:
            logger.error("Error during file upload")
            return "Error during file upload", 500
        logger.info("Upload process completed")

        logger.debug(f"process_selection completed at {time.time()}")
        return 'Files processed successfully!', 200

    except Exception as e:
        logger.exception(f"Unexpected error in process_selection: {str(e)}")
        return f"Unexpected error: {str(e)}", 500

if __name__ == '__main__':
    app.run(debug=True)

