import os
import threading
import logging
from datetime import datetime
from flask import Flask, render_template, request, send_from_directory
import paramiko
import ipaddress

app = Flask(__name__)

# Předem definované Scripty
AIROS_SCRIPT = "airos_script.sh"
AIROS6_SCRIPT = "airos6_script.sh"
AIROS8_SCRIPT = "airos8_script.sh"
MIPSBE_SCRIPT = "mipsbe_script.sh"
ARM_SCRIPT = "arm_script.sh"

# Vytvoření log souboru na základě aktuálního data
log_filename = f"device_scanner_{datetime.now().strftime('%Y%m%d')}.log"

# Konfigurace logování pro aktuální den
logging.basicConfig(
    filename=log_filename,
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)


def ssh_to_device(ip, username, password, port, results, lock):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        ssh.connect(ip, username=username, password=password, port=port, timeout=10)

        # Získání informace o zařízení
        try:
            stdin, stdout, stderr = ssh.exec_command("cat /etc/version")
            output = stdout.read().decode().lower().strip()

            if "airos" in output or "v6" in output or "v8" in output:
                script_type = "airos6"
                with open(AIROS6_SCRIPT, "r") as file:
                    commands = file.readlines()
            else:
                stdin, stdout, stderr = ssh.exec_command("/system resource print")
                output = stdout.read().decode().lower().strip()

                if "routeros" in output or "mikrotik" in output:
                    script_type = "mipsbe"
                    with open(MIPSBE_SCRIPT, "r") as file:
                        commands = file.readlines()
                else:
                    script_type = "none"
                    logging.warning(f"{ip} - Unknown device type. Exit: {output}")
                    commands = []  # Neznámý typ zařízení

        except Exception as e:
            script_type = "none"
            commands = []
            logging.error(f"{ip} - Chyba při detekci zařízení: {e}")

        # Spuštění příkazů
        if commands:
            for command in commands:
                ssh.exec_command(command.strip())

        result = {'ip': ip, 'status': 'OK', 'script': script_type}
        message = f"{ip} - Login: OK - Script: {script_type}"

    except paramiko.AuthenticationException:
        result = {'ip': ip, 'status': 'Login error', 'script': 'none'}
        message = f"{ip} - Login: Login error"

    except paramiko.SSHException as e:
        # Pokud je to timeout nebo jiné SSH problémy, ignorujte výstup v HTML
        if '[Errno None] Unable to connect' in str(e) or 'timed out' in str(e):
            result = {'ip': ip, 'status': 'Connection error', 'script': 'none'}
            message = f"{ip} - Connection error: {str(e)}"
            logging.error(f"{ip} - {str(e)}")  # Uložíme chybu do logu, ale neukážeme ji v HTML
            return  # Zamezí přidání této chyby do seznamu pro HTML zobrazení
        else:
            result = {'ip': ip, 'status': f'Chyba SSH: {e}', 'script': 'none'}
            message = f"{ip} - Login: Error SSH - {e}"

    except Exception as e:
        result = {'ip': ip, 'status': f'Chyba: {e}', 'script': 'none'}
        message = f"{ip} - Login: Error - {e}"

    # Ukládání výsledků a logování
    with lock:
        # Pokud je v chybovém hlášení text "Unable to connect" nebo "timed out",
        # nebude tento výsledek přidán do seznamu pro HTML zobrazení
        if "Unable to connect" not in message and "timed out" not in message:
            results.append(result)
        logging.info(message)



@app.route('/', methods=['GET', 'POST'])
def index():
    results = []
    log_files = []  # Seznam log souborů

    # Načítání log souborů v aktuálním adresáři
    log_directory = os.path.abspath('.')
    log_files = [f for f in os.listdir(log_directory) if f.endswith('.log')]  # Filtrujeme pouze log soubory

    if request.method == 'POST':
        network_ranges = request.form['network_ranges'].split(',')
        username = request.form['username']
        password = request.form['password']
        port = int(request.form['port'])

        threads = []
        results_lock = threading.Lock()

        for network in network_ranges:
            network = network.strip()
            try:
                net = ipaddress.ip_network(network)
                for ip in net.hosts():
                    ip_str = str(ip)
                    thread = threading.Thread(target=ssh_to_device, args=(ip_str, username, password, port, results, results_lock))
                    threads.append(thread)
                    thread.start()
            except ValueError:
                error_message = f"Chybný formát rozsahu: {network}"
                results.append({'ip': network, 'status': 'Invalid range', 'script': 'none'})
                logging.error(error_message)

        # Čekání na dokončení všech threadů
        for thread in threads:
            thread.join()

    return render_template('index.html', results=results if results else None, log_files=log_files)


from flask import Response

@app.route('/logs/<filename>')
def view_log(filename):
    try:
        log_file_path = os.path.join(os.getcwd(), filename)
        with open(log_file_path, 'r') as file:
            log_content = file.read()
        
        return Response(log_content, mimetype='text/plain')
    except FileNotFoundError:
        return "Log file not found", 404



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

