import ipaddress
import logging
import os
import time
import requests
import pandas as pd
import pycountry  # Aggiunto per ottenere il nome completo del paese

# Configurazione del logging
logging.basicConfig(
    level=logging.INFO,  # Cambia a DEBUG per più dettagli
    format='%(asctime)s - %(levelname)s - %(message)s'
)

def read_ip_block_file(file_path):
    ip_list = []
    if os.path.exists(file_path):
        with open(file_path, 'r') as f:
            for line in f:
                # Rimuovi tutto ciò che viene dopo l'indirizzo IP, inclusi i due punti
                ip_portion = line.strip().split(':')[0]
                # Verifica se l'IP è valido
                try:
                    ip_obj = ipaddress.ip_address(ip_portion)
                    if not ip_obj.is_private:
                        ip_list.append(ip_portion)
                    else:
                        logging.warning(f"L'indirizzo IP {ip_portion} è privato e verrà ignorato.")
                except ValueError:
                    logging.warning(f"Indirizzo IP non valido trovato nel file: {ip_portion}")
    else:
        logging.error(f"Il file {file_path} non esiste.")
    return ip_list

def get_bgpview_info(ip):
    try:
        url = f"https://api.bgpview.io/ip/{ip}"
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        data = response.json()
        return data
    except Exception as e:
        logging.error(f"Errore durante la richiesta a BGPView per {ip}: {e}")
        return None

def get_country_name(country_code):
    if not country_code:
        return ''
    try:
        country = pycountry.countries.get(alpha_2=country_code.upper())
        if country:
            return country.name
        else:
            logging.warning(f"Nome del paese non trovato per il codice: {country_code}")
            return country_code  # Ritorna il codice se il nome non è trovato
    except Exception as e:
        logging.error(f"Errore durante il recupero del nome del paese per il codice {country_code}: {e}")
        return country_code

def extract_bgpview_info(ip, data):
    if data is None or data.get('status') != 'ok':
        return None

    data = data.get('data', {})

    # Inizializza le variabili
    country_code = ''
    country_name = ''
    announced_prefix = ''
    asn = ''
    prefix_name = ''
    prefix_description = ''

    # Controlla se ci sono prefissi
    prefixes = data.get('prefixes', [])
    if prefixes:
        # Prendi il primo prefisso valido
        for prefix_info in prefixes:
            asn_info = prefix_info.get('asn', {})
            country_code = asn_info.get('country_code', '')
            if country_code:
                # Trovato un country_code, esci dal ciclo
                announced_prefix = prefix_info.get('prefix', '')
                asn = asn_info.get('asn', '')
                prefix_name = asn_info.get('name', '')
                prefix_description = asn_info.get('description', '')
                break  # Esci dal ciclo dopo aver trovato il country_code
        else:
            # Se nessun country_code è stato trovato nei prefissi
            logging.warning(f"Nessun country_code trovato nei prefissi per IP {ip}")
    else:
        logging.warning(f"Nessun prefisso annunciato trovato per IP {ip}")

    # Ottieni il nome del paese
    country_name = get_country_name(country_code)

    # Costruisci il dizionario con le informazioni estratte
    info = {
        'IP': ip,
        'Country Code': country_code,
        'Country Name': country_name,
        'Announced Prefix': announced_prefix,
        'Prefix Name': prefix_name,
        'Prefix Description': prefix_description,
        'ASN': asn
    }

    return info

def main():
    ip_block_file = 'ip_block.txt'
    ip_list = read_ip_block_file(ip_block_file)
    logging.info(f"Trovati {len(ip_list)} indirizzi IP da analizzare.")

    results = []

    for ip in ip_list:
        logging.info(f"Recupero informazioni da BGPView per {ip}...")
        data = get_bgpview_info(ip)
        info = extract_bgpview_info(ip, data)
        if info:
            results.append(info)
            logging.info(f"Informazioni per {ip} recuperate con successo.")
        else:
            logging.info(f"Non è stato possibile recuperare le informazioni per {ip}.")
            # Aggiungi una riga con valori vuoti
            results.append({
                'IP': ip,
                'Country Code': '',
                'Country Name': '',
                'Announced Prefix': '',
                'Prefix Name': '',
                'Prefix Description': '',
                'ASN': ''
            })
        # Aggiungere una pausa per evitare rate limiting
        time.sleep(1)

    # Creare un DataFrame Pandas per il report
    df = pd.DataFrame(results)

    # Stampa il report
    print("\n--- Report BGPView ---\n")
    if not df.empty:
        print(df[['Country Name', 'Announced Prefix', 'Prefix Name', 'Prefix Description', 'ASN']].to_string(index=False))
    else:
        print("Nessun dato disponibile per generare il report.")

if __name__ == "__main__":
    main()
