import os
import subprocess
import shutil
import json

def analyze_ipa_with_ipanalyze(ipa_path):
    """
    Analyze an IPA file using the ipanalyze Go tool.

    Args:
        ipa_path (str): Path to the IPA file.

    Returns:
        dict: Extracted metadata from the IPA file, or None if extraction fails.
    """
    try:
        # Ensure ipanalyze binary is available
        ipanalyze_binary = './appanalyze'  # Assuming 'appanalyze' is the compiled binary
        if not os.path.isfile(ipanalyze_binary):
            print(f"Error: {ipanalyze_binary} not found. Make sure the binary exists in the current directory.")
            return None

        # Run ipanalyze on the IPA file
        result = subprocess.run(
            [ipanalyze_binary, ipa_path],
            capture_output=True,
            text=True
        )

        # Check for errors
        if result.returncode != 0:
            print(f"Error analyzing IPA: {result.stderr.strip()}")
            return None

        # Parse the output of ipanalyze and extract the metadata
        output = result.stdout.strip()
        metadata = {}
        for line in output.splitlines():
            if line.startswith("[*]"):
                key, value = line[4:].split(":", 1)
                metadata[key.strip()] = value.strip()

        return metadata
    except Exception as e:
        print(f"Error running ipanalyze: {e}")
        return None

def update_repo_json(repo_data, ipa_filename, app_info, base_url):
    """
    Update the repo.json file with app information.

    Args:
        repo_data (dict): Existing repository data.
        ipa_filename (str): Filename of the IPA.
        app_info (dict): Extracted app information.
        base_url (str): Base URL for serving files.

    Returns:
        dict: Updated repository data.
    """
    # Safely access 'name' and other fields in app_info
    app_name = app_info.get('name', ipa_filename)  # Default to the IPA filename if 'name' is not found
    bundle_id = app_info.get('bundle id', 'unknown')
    version = app_info.get('short version', 'unknown')

    # Construct download URL for the IPA
    ipa_download_url = f"{base_url}/ipas/{ipa_filename}"

    # Create or update app entry
    app_entry = {
        'name': app_name,  # Use the name from the IPA filename or fallback to the filename
        'bundleIdentifier': bundle_id,
        'developerName': f"{app_name} Developer",  # Placeholder for developer name
        'version': version,
        'versionDate': "2024-10-27",  # Placeholder for version date
        'downloadURL': ipa_download_url,
        'localizedDescription': f"{app_name} description",  # Placeholder for description
        'iconURL': app_info.get('iconURL', ''),  # Icon URL, if available
        'tintColor': "FFC300",  # Placeholder for tint color
        'size': 0,  # Placeholder for size (you may want to calculate this)
        'screenshotURLs': []  # Placeholder for screenshot URLs
    }

    # Update repository data
    if 'apps' not in repo_data:
        repo_data['apps'] = []  # Initialize the apps list if it doesn't exist

    repo_data['apps'].append(app_entry)

    return repo_data

def create_repo_json(ipa_files, img_dir, base_url):
    """
    Create a new repository JSON structure from IPA files.

    Args:
        ipa_files (list): List of IPA filenames.
        img_dir (str): Directory to save extracted icons.
        base_url (str): Base URL for serving files.

    Returns:
        dict: New repository data.
    """
    repo_data = {
        "name": "Inject repo",  # Set your repository name
        "identifier": "com.idk.inject",  # Set your identifier
        "subtitle": ".",  # Set subtitle
        "iconURL": f"{base_url}/img/RepoIcon.png",  # Set repo icon URL
        "website": base_url,  # Set website URL
        "sourceURL": f"{base_url}/repo.json",  # Set source URL for the repo
        "tintColor": "FFC300",  # Example color
        "featuredApps": [],  # You can populate this later
        "apps": []  # Initialize with an empty apps list
    }

    # Process each IPA file
    for ipa_filename in ipa_files:
        ipa_path = os.path.join(ipa_dir, ipa_filename)
        print(f"\nProcessing {ipa_filename}...")

        # Extract IPA information using ipanalyze
        app_info = analyze_ipa_with_ipanalyze(ipa_path)

        # If the app_info is valid, update repo.json
        if app_info:
            print("Extracted App Information:")
            print(f"App Name: {app_info.get('display name', 'N/A')}")
            print(f"Bundle Identifier: {app_info.get('bundle id', 'N/A')}")
            print(f"Version: {app_info.get('short version', 'N/A')}")
            # Assume that icon URL extraction happens later if needed
            icon_url = f"{base_url}/img/{app_info.get('bundle id', 'unknown')}.png"

            # Update repository data
            app_info['iconURL'] = icon_url
            repo_data = update_repo_json(repo_data, ipa_filename, app_info, base_url)
        else:
            print(f"Failed to extract information from {ipa_filename}")

    return repo_data

def main():
    # Predefined directories and base URL
    global ipa_dir
    ipa_dir = './ipas'
    img_dir = './img'
    base_url = 'https://ipa.tresinteressant.site'

    # Ensure directories exist
    os.makedirs(ipa_dir, exist_ok=True)
    os.makedirs(img_dir, exist_ok=True)

    # Find all IPA files in the directory
    ipa_files = [f for f in os.listdir(ipa_dir) if f.endswith('.ipa')]

    if not ipa_files:
        print(f"No IPA files found in {ipa_dir}")
        return

    # Create a new repository data structure
    repo_data = create_repo_json(ipa_files, img_dir, base_url)

    # Save updated repository data
    with open('./repo.json', 'w') as f:
        json.dump(repo_data, f, indent=2)

    print("\nRepository data updated in repo.json")

if __name__ == "__main__":
    main()
