import requests
import os
import concurrent.futures
from urllib.parse import urlparse, unquote

SONGS_URL = [
]

ACCESS_KEY = ""

# Directory to save the downloaded songs
DOWNLOAD_DIR = "downloaded_songs"

# Number of concurrent downloads
MAX_WORKERS = 5

def download_song(url):
    """
    Downloads a single song from a URL and saves it to the download directory.
    """
    try:
        # --- Create a safe filename from the URL ---
        # This handles cases where the filename in the URL contains encoded
        # characters like '%2F' (a slash), which can cause issues.

        # 1. Remove the query string (e.g., '?accessKey=...')
        url_path = url.split('?', 1)[0]

        # 2. Get the part of the URL after the last slash
        filename_encoded = url_path.rsplit('/', 1)[-1]

        # 3. URL-decode the filename (e.g., 'foo%2Fbar.m4a' -> 'foo/bar.m4a')
        filename_decoded = unquote(filename_encoded)
        
        # 4. Replace any slashes with underscores to create a valid, flat filename
        filename = filename_decoded.replace('/', '_')

        # Create the full path to save the file
        filepath = os.path.join(DOWNLOAD_DIR, filename)

        print(f"Starting download: {filename}")

        # --- Perform the download ---
        # The 'requests.get' method fetches the content from the URL.
        # 'stream=True' is important for large files as it doesn't load the
        # entire content into memory at once.
        with requests.get(url, stream=True) as response:
            # Check if the request was successful (HTTP status code 200)
            response.raise_for_status()

            # --- Save the file in chunks ---
            # Open the local file in write-binary mode ('wb')
            with open(filepath, 'wb') as f:
                # Iterate over the response content in chunks of 8KB
                for chunk in response.iter_content(chunk_size=8192):
                    f.write(chunk)
        
        print(f"Finished download: {filename}")
        return f"Successfully downloaded {filename}"

    except requests.exceptions.RequestException as e:
        return f"Failed to download {url}. Error: {e}"
    except Exception as e:
        return f"An error occurred with {url}. Error: {e}"

def main():
    """
    Main function to set up the download environment and start the concurrent downloads.
    """
    # --- Create the download directory if it doesn't exist ---
    if not os.path.exists(DOWNLOAD_DIR):
        os.makedirs(DOWNLOAD_DIR)
        print(f"Created directory: {DOWNLOAD_DIR}")

    # --- Use a ThreadPoolExecutor for concurrent downloads ---
    # This creates a pool of threads to download multiple files at the same time.
    # It's much faster than downloading them one by one.
    with concurrent.futures.ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        # 'executor.map' applies the 'download_song' function to each URL in the list.
        # It returns an iterator for the results, which we loop through.
        results = executor.map(download_song, SONGS_URL)

        # Print the result of each download (success or failure message)
        for result in results:
            print(result)

    print("\nAll download tasks are complete.")

# --- Run the script ---
# This ensures the 'main' function is called only when the script is executed directly.
if __name__ == "__main__":
    main()

