import requests
import os
import time
import json

# --- CONFIGURATION ---
API_KEY = "4c527b8a0a9c295d80bf7c48093a8b01ccab58787742758f7aa912bdac1141fb" # Make sure your premium key is pasted here
DOWNLOAD_DIR = "virustotal_samples"
LIMIT = 100
# For premium keys, the rate limit is much higher. A 1-2 second delay is safe.
DELAY_BETWEEN_REQUESTS_SEC = 2 

# --- SCRIPT ---
BASE_URL = "https://www.virustotal.com/api/v3"


def get_latest_file_hashes():
    """
    Fetches latest file hashes using the correct VirusTotal Intelligence
    search endpoint and the correct 'order' parameter.
    """
    search_url = f"{BASE_URL}/intelligence/search"
    print(f"\n[DEBUG] Using the Intelligence Search endpoint: {search_url}")

    headers = {"x-apikey": API_KEY, "Accept": "application/json"}
    
    # CORRECTED 'order' parameter based on the API's error message.
    params = {
        'order': 'last_submission_date',
        'limit': LIMIT,
        'query': 'submissions:1+'
    }
    print(f"[DEBUG] Using parameters: {params}")
    
    try:
        print("[DEBUG] Sending GET request to the Intelligence Search API...")
        response = requests.get(search_url, headers=headers, params=params, timeout=30)
        
        print(f"[DEBUG] Received HTTP Status Code: {response.status_code}")
        response.raise_for_status()
        
        print("[DEBUG] Response seems OK. Attempting to decode JSON...")
        search_results = response.json().get('data', [])
        
        if not search_results:
            print("[!] The API response was successful but contained no search results.")
            return []
            
        hashes = [item['id'] for item in search_results]
        print(f"[+] SUCCESS: Fetched {len(hashes)} file hashes.")
        return hashes

    except requests.exceptions.HTTPError as e:
        print(f"\n[!] FATAL HTTP ERROR: {e}")
        print(f"[!] The server responded with a {e.response.status_code} error.")
        if e.response.status_code == 401:
            print("[!] ADVICE: A 401 'Unauthorized' error means your API key is likely incorrect or expired.")
        print(f"[!] Server Response Body: {e.response.text}")
        
    except requests.exceptions.RequestException as e:
        print(f"\n[!] FATAL NETWORK ERROR: {e}")
        
    return []


def download_file(file_hash):
    """Downloads a single file, assuming a premium key."""
    print(f"\n[*] Preparing to download file with hash: {file_hash}")
    download_url_endpoint = f"{BASE_URL}/files/{file_hash}/download_url"
    headers = {"x-apikey": API_KEY}
    
    try:
        response = requests.get(download_url_endpoint, headers=headers, timeout=20)
        response.raise_for_status()

        actual_download_link = response.json().get('data')

        if not actual_download_link:
            print(f"[!] Could not retrieve a download link for hash {file_hash}.")
            return False

        print("[*] Got temporary URL. Now downloading file content...")
        file_response = requests.get(actual_download_link, timeout=60)
        file_response.raise_for_status()

        file_path = os.path.join(DOWNLOAD_DIR, file_hash)
        with open(file_path, "wb") as f:
            f.write(file_response.content)
        
        print(f"[+] Successfully downloaded and saved to: {file_path}")
        return True

    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 404:
            print(f"[!] File not found on VirusTotal for hash: {file_hash}")
        else:
            print(f"[!] HTTP Error during download for {file_hash}: {e}")
    except requests.exceptions.RequestException as e:
        print(f"[!] A network error occurred during download for {file_hash}: {e}")
        
    return False


def main():
    """Main function to run the script."""
    print("--- VirusTotal Sample Downloader ---")
    if API_KEY == "YOUR_VIRUSTOTAL_API_KEY" or not API_KEY:
        print("\n[!] FATAL ERROR: Please set your VirusTotal API key in the 'API_KEY' variable.")
        return

    if not os.path.exists(DOWNLOAD_DIR):
        print(f"[*] Creating download directory: {DOWNLOAD_DIR}")
        os.makedirs(DOWNLOAD_DIR)

    file_hashes = get_latest_file_hashes()
    
    if not file_hashes:
        print("\n[!] SCRIPT ENDING: No file hashes were retrieved. Please check any FATAL ERROR messages above.")
        return

    download_count = 0
    for i, file_hash in enumerate(file_hashes):
        print(f"\n--- Processing file {i+1}/{len(file_hashes)} ---")
        if download_file(file_hash):
            download_count += 1
        
        if i < len(file_hashes) - 1:
            print(f"[*] Waiting for {DELAY_BETWEEN_REQUESTS_SEC} seconds...")
            time.sleep(DELAY_BETWEEN_REQUESTS_SEC)
        
    print(f"\n--- SCRIPT COMPLETE ---")
    print(f"Successfully downloaded {download_count} out of {len(file_hashes)} targeted files.")


if __name__ == "__main__":
    main()